Mockito单元测试checkMail方法出现参数不匹配错误该如何解决?
问题原因
你测试类中通过@Mock生成的QueryWrapper实例,并没有被业务代码使用。checkMail方法执行时会内部自行new一个全新的QueryWrapper实例,Mockito默认按照对象引用匹配参数,两个实例地址不同自然会报参数不匹配的错误,你声明的Mock QueryWrapper完全是多余的,可以直接删除。
解决方案
方案1:使用参数匹配器忽略实例匹配(快速验证调用)
如果只需要验证opeSupplierMapper的selectCount方法被调用,不需要校验查询条件是否正确,直接用Mockito的any()匹配器即可,修改测试代码如下:
class SupplierRosServiceImplTest { @InjectMocks SupplierRosServiceImpl supplierRosService; @Mock private OpeSupplierMapper ope; @Test void ItShouldCheckMail() { // 先给selectCount方法打桩,指定返回值 when(ope.selectCount(any(QueryWrapper.class))).thenReturn(0); // 执行被测方法 Boolean result = supplierRosService.checkMail("myEmailAdress", "123456"); // 验证方法调用 verify(ope).selectCount(any(QueryWrapper.class)); // 验证返回结果符合预期 assertTrue(result); } }
方案2:使用参数捕获器校验查询条件(更严谨)
如果需要验证checkMail方法构造的查询条件是否正确,可以用ArgumentCaptor捕获实际传入的QueryWrapper,再校验内部的查询参数:
class SupplierRosServiceImplTest { @InjectMocks SupplierRosServiceImpl supplierRosService; @Mock private OpeSupplierMapper ope; // 也可以用@Captor注解直接声明捕获器,无需手动实例化 @Captor private ArgumentCaptor<QueryWrapper<OpeSupplier>> captor; @Test void ItShouldCheckMail() { // 打桩模拟数据库存在相同邮箱的记录 when(ope.selectCount(any(QueryWrapper.class))).thenReturn(1); // 执行被测方法 Boolean result = supplierRosService.checkMail("myEmailAdress", "123456"); // 验证调用同时捕获参数 verify(ope).selectCount(captor.capture()); // 校验查询条件是否符合预期 QueryWrapper<OpeSupplier> actualWrapper = captor.getValue(); assertEquals("myEmailAdress", actualWrapper.getParamNameValuePairs().get(OpeSupplier.COL_CONTACT_EMAIL)); assertEquals(0, actualWrapper.getParamNameValuePairs().get(OpeSupplier.COL_DR)); assertEquals(123456L, actualWrapper.getParamNameValuePairs().get(OpeSupplier.COL_ID)); // 校验返回结果(存在重复邮箱应该返回false) assertFalse(result); } }
内容的提问来源于stack exchange,提问作者ced_d0llars
相关产品推荐
相关产品推荐

