在namedParameterJdbcTemplate中对GeneratedKeyHolder进行单元测试

Gle*_*eeb 4 java spring unit-testing mockito

我正在尝试将单元测试写入包含以下代码的函数:

    KeyHolder newCode = new GeneratedKeyHolder();
    try {
        namedParameterJdbcTemplate.update(sql, paramMap, newCode);
    } catch (DuplicateKeyException e) {
        logger.error("Duplicate Key");
    }
    data.setId(newCode.getKey().intValue());
Run Code Online (Sandbox Code Playgroud)

现在,在使用Mockito时:

Mockito.when(namedParameterJdbcTemplate.update(Mockito.anyString(), Mockito.any(MapSqlParameterSource.class), Mockito.any(GeneratedKeyHolder.class))).thenReturn(1);
Run Code Online (Sandbox Code Playgroud)

那我该如何填充GeneratedKeyHolder数据呢?

谢谢.

Jam*_*mey 8

我会通过以下方式之一来做到这一点:

  1. 注入密钥.
  2. 存根方法调用并在那里设置密钥.

方法1 当我说注入密钥时,我实际上意味着注入一个KeyFactory.这意味着您可以在测试中控制结果.例如:

KeyHolder newCode = injectedKeyFactory.getKeyHolder();
try {
    namedParameterJdbcTemplate.update(sql, paramMap, newCode);
} catch (DuplicateKeyException e) {
    logger.error("Duplicate Key");
}
data.setId(newCode.getKey().intValue());
Run Code Online (Sandbox Code Playgroud)

然后在测试中:

KeyHolder newCode = mock(KeyHolder.class);
Mockito.when(namedParameterJdbcTemplate.update(Mockito.anyString(), Mockito.any(MapSqlParameterSource.class), newCode)).thenReturn(1);
Mockito.when(newCode.getKey()).thenReturn(__preferredId__);
Run Code Online (Sandbox Code Playgroud)

关键工厂是一个简单的工厂,只返回一个新的GeneratedKeyHolder.它在施工时被注入,所以这种方法确实假设你正在使用DI.

方法2

Mockito.when(namedParameterJdbcTemplate.update(Mockito.anyString(), Mockito.any(MapSqlParameterSource.class), Mockito.any(GeneratedKeyHolder.class))).thenAnswer(new Answer() {
    Object answer(InvocationOnMock invocation) {
        Object[] args = invocation.getArguments();
        Map<String, Object> keyMap = new HashMap<String, Object>();
        keyMap.put("", __preferredId__);
        ((GeneratedKeyHolder)args[2]).getKeyList().add(keyMap);
    }
}).andReturn(1);
Run Code Online (Sandbox Code Playgroud)

我没有真正使用过Mockito,很抱歉,如果代码不太正确的话.:)

  • 很好的答案!,我使用了第二种方法。唯一缺少的是 return 语句。如果你想完全返回我想要的,它应该在最后声明“返回 1” (2认同)