Java 单元测试在namedParameterJdbcTemplate中生成密钥持有者
我正在尝试为包含以下代码的函数编写单元测试: 现在,在使用Mockito时:Java 单元测试在namedParameterJdbcTemplate中生成密钥持有者,java,spring,unit-testing,mockito,Java,Spring,Unit Testing,Mockito,我正在尝试为包含以下代码的函数编写单元测试: 现在,在使用Mockito时: Mockito.when(namedParameterJdbcTemplate.update(Mockito.anyString(), Mockito.any(MapSqlParameterSource.class), Mockito.any(GeneratedKeyHolder.class))).thenReturn(1); 那么,我应该如何用数据填充生成的钥匙夹 谢谢。我会用以下方法之一: 注入密钥 Stub方法
Mockito.when(namedParameterJdbcTemplate.update(Mockito.anyString(), Mockito.any(MapSqlParameterSource.class), Mockito.any(GeneratedKeyHolder.class))).thenReturn(1);
那么,我应该如何用数据填充生成的钥匙夹
谢谢。我会用以下方法之一:
KeyHolder newCode = injectedKeyFactory.getKeyHolder();
try {
namedParameterJdbcTemplate.update(sql, paramMap, newCode);
} catch (DuplicateKeyException e) {
logger.error("Duplicate Key");
}
data.setId(newCode.getKey().intValue());
然后在测试中:
KeyHolder newCode = mock(KeyHolder.class);
Mockito.when(namedParameterJdbcTemplate.update(Mockito.anyString(), Mockito.any(MapSqlParameterSource.class), newCode)).thenReturn(1);
Mockito.when(newCode.getKey()).thenReturn(__preferredId__);
密钥工厂是一个简单的工厂,它只返回新生成的密钥持有者。它在构建时被注入,所以这个方法假设您正在使用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);
Mockito.when(namedParameterJdbcTemplate.update(Mockito.anyString(),Mockito.any(MapSqlParameterSource.class),Mockito.any(GeneratedKeyHolder.class))。然后回答(new Answer(){
对象应答(调用锁调用){
对象[]args=invocation.getArguments();
Map keyMap=newhashmap();
keyMap.put(“”,_preferredId_;);
((GeneratedKeyHolder)args[2]).getKeyList().add(keyMap);
}
})安德烈图恩(1);
我没有真正使用Mockito,如果代码不太正确,那么很抱歉。:) 这对我很有效。这与上面的答案略有不同 正在测试的类
将KeyHolder工厂声明为类属性并注入构造函数:
private final NamedParameterJdbcTemplate jdbcTemplate;
private final GeneratedKeyHolderFactory keyHolderFactory;
public AccountJdbcAdapter(NamedParameterJdbcTemplate jdbcTemplate, GeneratedKeyHolderFactory keyHolderFactory) {
this.keyHolderFactory = keyHolderFactory;
this.jdbcTemplate = jdbcTemplate;
}
private Long executeCreateAccount(Account newAccount){
KeyHolder keyHolder = keyHolderFactory.newKeyHolder();
jdbcTemplate.update(
queryCreateAccount,
createAccountParams(newAccount),
keyHolder
);
YOU WILL INJECT MOCKED VALUE HERE -->
Long accountId = keyHolder.getKey().longValue();
}
为工厂声明类
@Component
public class GeneratedKeyHolderFactory {
public GeneratedKeyHolderFactory(){
}
public KeyHolder newKeyHolder() {
return new GeneratedKeyHolder();
}
}
测试:
模拟工厂,获得一个新的KeyHolder实例并用值填充
private final GeneratedKeyHolderFactory factory = mock(GeneratedKeyHolderFactory.class);
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate = mock(NamedParameterJdbcTemplate.class);
private final AccountJdbcAdapter accountJdbcAdapter = new AccountJdbcAdapter(namedParameterJdbcTemplate, factory);
void createAccountsOk() {
KeyHolder keyHolder = new GeneratedKeyHolder(Arrays.asList(Map.of("accountId", accountId)));
when(factory.newKeyHolder()).thenReturn(keyHolder);
when(namedParameterJdbcTemplate.update(any(), any(MapSqlParameterSource.class), any(GeneratedKeyHolder.class))).thenReturn(1);
回答得好!,我使用了第二种方法。唯一缺少的是返回语句。如果您想准确地返回我想要的内容,它应该在“return1”结尾处声明
private final GeneratedKeyHolderFactory factory = mock(GeneratedKeyHolderFactory.class);
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate = mock(NamedParameterJdbcTemplate.class);
private final AccountJdbcAdapter accountJdbcAdapter = new AccountJdbcAdapter(namedParameterJdbcTemplate, factory);
void createAccountsOk() {
KeyHolder keyHolder = new GeneratedKeyHolder(Arrays.asList(Map.of("accountId", accountId)));
when(factory.newKeyHolder()).thenReturn(keyHolder);
when(namedParameterJdbcTemplate.update(any(), any(MapSqlParameterSource.class), any(GeneratedKeyHolder.class))).thenReturn(1);