【问题标题】:Unit test GeneratedKeyHolder in namedParameterJdbcTemplatenamedParameterJdbcTemplate 中的单元测试 GeneratedKeyHolder
【发布时间】:2014-04-07 10:10:48
【问题描述】:

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

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

现在,在使用 Mockito 时:

Mockito.when(namedParameterJdbcTemplate.update(Mockito.anyString(), Mockito.any(MapSqlParameterSource.class), Mockito.any(GeneratedKeyHolder.class))).thenReturn(1);

那么我应该如何用数据填充GeneratedKeyHolder

谢谢。

【问题讨论】:

    标签: java spring unit-testing mockito


    【解决方案1】:

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

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

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

    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__);
    

    密钥工厂是一个简单的工厂,它只返回一个新的 GeneratedKeyHolder。它是在构建时注入的,因此此方法确实假设您使用的是 DI。

    方法二

    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,如果代码不太正确,请见谅。 :)

    【讨论】:

    • 好答案!,我使用了第二种方法。唯一缺少的是返回声明。如果你想准确地返回我想要的,它应该在最后声明“return 1”
    【解决方案2】:

    这对我有用。与上面的答案略有不同。

    正在测试的类
    将 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);
    

    【讨论】:

      猜你喜欢
      • 2021-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-13
      • 2013-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多