Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 单元测试在namedParameterJdbcTemplate中生成密钥持有者_Java_Spring_Unit Testing_Mockito - Fatal编程技术网

Java 单元测试在namedParameterJdbcTemplate中生成密钥持有者

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时:

Mockito.when(namedParameterJdbcTemplate.update(Mockito.anyString(), Mockito.any(MapSqlParameterSource.class), Mockito.any(GeneratedKeyHolder.class))).thenReturn(1);
那么,我应该如何用数据填充
生成的钥匙夹


谢谢。

我会用以下方法之一:

  • 注入密钥
  • Stub方法调用并在那里设置键
  • 方法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);