前言:进行单元测试时,有时候无法编写合适的测试用例来满足流程中的异常捕获和catch内的后续操作,此时mock模拟就有大作用了
例如:在进行删除操作时,为了防止在删除过程中突发数据库断连等情况,使用了try、catch进行异常的捕获和输出,但是在单元测试中编写测试实例时不可能实现这一种操作,所以就需要使用mock来模拟抛出异常
try {
Boolean entity = targetMapper.deleteComment(id);
if (entity) {
return RestResponse.ok().message("删除成功");
}
return RestResponse.failed().message("删除失败");
} catch (Exception e) {
return RestResponse.failed().message("删除失败,出现异常");
}
实现代码如下,慢慢解释
@Test
public void testDeleteExceptionTest() throws Exception{
//删除失败,出现异常
//输入数据
CareCourseComment careCourseComment = new CareCourseComment();
careCourseComment.setId((long)106172);
//预期结果
RestResponse<CareCourseComment> careCourseCommentRestResponse = RestResponse.failed().message("删除失败,出现异常");
//赋值
Long id = careCourseComment.getId();
//mock模拟失败
CareCourseCommentMapper careCourseCommentMapper = mock(CareCourseCommentMapper.class);
//范围设置
ReflectionTestUtils.setField(targetService,"targetMapper",careCourseCommentMapper);
when(careCourseCommentMapper.deleteComment(anyLong())).thenThrow(new RuntimeException());
//断言
RestResponse<CareCourseComment> entity = targetService.deleteComment(id);
ReflectionTestUtils.setField(targetService,"targetMapper",targetMapper);
assertEquals(careCourseCommentRestResponse,entity);
}
前面的输入数据和预期结果就不讲了,直接进入正题--mock模拟
首先需要对调用的Mapper层进行模拟,因为使用原来的Mapper肯定不会返回我们所想要的返回值,也不可能出现异常等情况。之后便是进行范围设置,使用ReflectionTestUtils.setField进行范围限制,我们限制于Service层下调用的targetMapper层,令其替换成我们所模拟的mapper,接下来使用when().thenThrow()方法保证我们在进行deleteComment方法时不管传入的是什么值都会抛出异常,后续则是进行断言,结果比对。文章来源:https://uudwc.com/A/LRYng
这里需要注意:在验证完后需要对Service的targetMapper进行还原!!!否则会导致其他的测试类也会被这个mock模拟的Mapper所替换。可能导致当整一个测试类进行运行时,会使得其他的测试类与预期结果出现大偏差甚至报错,在debug的过程下,可以清楚地看到Service层的targetMapper是由mock模拟的。文章来源地址https://uudwc.com/A/LRYng