JUnit可以同时使用verify()和doReturn()吗?

n1bvdmb6  于 2022-11-11  发布在  其他
关注(0)|答案(1)|浏览(430)

我有一些使用CompletableFutures的异步调用,我的单元测试失败了。大多数时候它们没有失败,但是偶尔它们可能会失败...我得到的错误消息是:

org.mockito.exceptions.misusing.PotentialStubbingProblem: 
Strict stubbing argument mismatch. Please check:
 - this invocation of 'queryForList' method:
    namedParameterJdbcTemplate.queryForList(
    null,
    MapSqlParameterSource {id=0},
    class java.lang.String
);
...
Typically, stubbing argument mismatch indicates user mistake when writing tests.
Mockito fails early so that you can debug potential problem easily.
However, there are legit scenarios when this exception generates false negative signal:
  - stubbing the same method multiple times using 'given().will()' or 'when().then()' API
    Please use 'will().given()' or 'doReturn().when()' API for stubbing.
  - stubbed method is intentionally invoked with different arguments by code under test
    Please use default or 'silent' JUnit Rule (equivalent of Strictness.LENIENT).

我试过使用doReturn().when(),但它仍然给出同样的错误。使用Mockito.lenient()修复了它,但我觉得使用Mockito.verify()方法是解决这个存根/异步问题的正确方法。
添加验证和模拟后返回:

Mockito.verify(namedParameterJdbcTemplate, Mockito.timeout(100).times(1)).queryForList(Mockito.anyString(), Mockito.any(MapSqlParameterSource.class), Mockito.eq(String.class));
        Mockito.verify(namedParameterJdbcTemplate, Mockito.timeout(100).times(1)).query(Mockito.anyString(), Mockito.any(MapSqlParameterSource.class), Mockito.any(BasicMapper.class));

        Mockito.when(namedParameterJdbcTemplate.queryForList(Mockito.anyString(), Mockito.any(MapSqlParameterSource.class), Mockito.eq(String.class))).thenReturn(null);
        Mockito.when(namedParameterJdbcTemplate.query(Mockito.anyString(), Mockito.any(MapSqlParameterSource.class), Mockito.any(BasicMapper.class))).thenReturn(offerEvents);

我收到此错误

Wanted but not invoked:
namedParameterJdbcTemplate.queryForList
...
Actually, there were zero interactions with this mock.

我解决此问题的最佳方法是什么?

pdkcd3nj

pdkcd3nj1#

您没有显示完整的测试代码,但您可能将verify放在了正在测试的代码之前。请将其移动到正在测试的代码之后。
when用于设置mock,因此必须在调用mock以获取数据的代码 * 之前 * 调用它。
verify检查是否在mock上按预期调用了一个方法,因此它必须在调用mock的代码 * 之后 * 调用,否则什么都没有发生,验证将失败。
顺便说一句,如果您的代码还验证了一个依赖于mock提供的数据的结果,那么实际上没有必要在mock上也执行验证:根据使用when完成的设置获得预期数据的事实应该足以确认调用了mock。

相关问题