背景
如果写单元测试,mock必不可少;Mock是解决单元测试UT里依赖问题的重要手段;其实mock是个很简单的概念,不要害怕。
代码有依赖(not self contained)
单元测试目的是只测试某个模块,不需要测试他的依赖;但是实际工作中,肯定存在依赖的问题,controller和service,dao都是有依赖的。
- 如果我们只单元测试controller,但是不希望同时测试service和dao;有可能是数据库有问题,也有可能是service和dao还没写好,无论怎样都希望不要影响controller的测试;
- 问题:如何不用执行likeService和commentService,就可以测试LikeController的方法呢?
@Controller
public class LikeController {
private static final Logger logger = LoggerFactory.getLogger(LikeController.class);
@Autowired
LikeService likeService;
@Autowired
CommentService commentService;
@RequestMapping(path = {"/like"}, method = RequestMethod.POST)
@ResponseBody
public String like(@RequestParam("commentId") int commentId) {
Comment comment = commentService.getCommentById(commentId);
long likeCount = likeService.like(hostHolder.getUser().getId(), EntityType.ENTITY_COMMENT, commentId);
return WendaUtil.getJSONString(0, String.valueOf(likeCount));
}
}
使用MOCK对象
模拟虚拟对象,模拟likeService和commentService对象;
调用commentService.getCommentById()时,直接根据输入参数,返回一个Comment对象;不要执行service真实代码段;
MOCK对象如何工作
java生态中有两种mock框架;
- mockito为代表,代理对象(proxy object)是有mock框架创建的对象,是一个假的service对象。通过框架创建依赖对象,不能new MyObject();这应该是代理设计模式。后面分享一下代理模式。
- jmockit的做法,类加载器重新映射类文件;可以用new 来创建依赖对象,比代理更强大;但是更加复杂;