Junit Test之Easy Mock Test入门
这一段时间公司的项目进行分模块分层进行专人维护开发,所以就会有不同的service和dao有不同的人来开发,这里我们假设service和dao不同的人开发,service是依赖dao的,如果我们的dao开发人员比较忙并没有把dao模块开发好,service如果要对自己的模块进行测试该怎么做呢?这个时候我们的Easy Mock Test就可以派上用场了。
首先开发service的和dao的会讨论商量出来一套接口,假设dao的接口如下:
package cn.bridgeli.dao; import cn.bridgeli.model.User; public interface UserDao { public User getUserById(int id); public User getUserByUsername(String username); //... }
dao模块的小朋友把它打成一个jar包,扔给service开发人员,然后我们亲爱的service开发人员就自己玩去了,最后我们的service开发人员完成了自己的任务,写下了如下的代码,当然这只是一个demo而已:
package cn.bridgeli.service.impl; import cn.bridgeli.dao.UserDao; import cn.bridgeli.model.User; import cn.bridgeli.service.UserService; public class UserServiceImpl implements UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public boolean login(String username, String password) { User user = userDao.getUserByUsername(username); System.out.println("id==" + user.getId()); if (user != null) { String passwordInDao = user.getPassword(); if (passwordInDao != null && passwordInDao.equalsIgnoreCase(password)) { return true; } } return false; } @Override public User getUserById(int userId) { return userDao.getUserById(userId); } }
但是我们的service怎么知道自己写的有没有问题呢?现在我们的service想对自己的模块进行测试,但dao开发人员还没开始,这肯定是没办法开始的,那么怎么办呢?很简单,只需要这么做就可以了:
package cn.bridgeli.service; import org.easymock.EasyMock; import org.junit.Assert; import org.junit.Test; import cn.bridgeli.dao.UserDao; import cn.bridgeli.model.User; import cn.bridgeli.service.impl.UserServiceImpl; public class UserServiceTest { //@Test(expected = RuntimeException.class) @Test public void testLogin() { String userName = "bridgeli"; String password = "abc123_"; //1、创建mock对象,以接口形式创建 UserDao userDao= EasyMock.createMock(UserDao.class); //2、设定参预期和返回,查询预期值得到所设定的预期结果 User user = new User(); user.setId(1); user.setUserName("bridgeli"); user.setPassword("abc123_"); //... EasyMock.expect(userDao.getUserByUsername("bridgeli")).andReturn(user).times(1); // userDao.getUserById(1); // EasyMock.expectLastCall().andReturn(user); // userDao.getUserByUserName(userName); EasyMock.expectLastCall(); //3、结束录制 EasyMock.replay(userDao); UserService userService = new UserServiceImpl(); ((UserServiceImpl)userService).setUserDao(userDao); boolean loginResult = userService.login(userName, password); Assert.assertTrue(loginResult); //User userIdDao = userService.getUserById(1); //Assert.assertNotNull(userIdDao); //4、回放录制 EasyMock.verify(userDao); } }
这就要求我们引入EasyMock的类库,pom文件如下:
<dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> <version>3.4</version> </dependency>
现在我们直接跑这个test是可以直接跑的,需要说明的是:
1. EasyMock.expect(userDao.getUserByUsername(“bridgeli”))
.andReturn(user).times(1) 是指我们要调用dao中的getUserByUsername时,返回user对象。
2. times以为调用的次数,默认就是1,否则调几次就是写几。
3. 我们给service和传的参数是bridgeli,所以返回的user对象和我们定义的一样,测试通过,但如果我们传的参数是其他的肯定就不行了,那么如果我们不希望是固定参数呢?这时候我们可以这么做,把:
EasyMock.expect(userDao.getUserByUsername("bridgeli")).andReturn(user).times(1)
改成:
EasyMock.expect(userDao.getUserByUsername(EasyMock.isA(String.class))).andReturn(user).times(1)
就好了,除此之外还有一些常用的方法:
anyInt(),anyObject(),isNull(),same(),startsWith()等等
4. 期待方法返回异常,可以这么做(面向异常编程):
EasyMock.expect(userDao.getUserByUsername("bridgeli")).andThrow(new RuntimeException()).times(1)
具体还有很多方法,但因为这是一个入门教程,所以师傅领进门,修行在个人,就留给读者大胆的去测试EasyMock里面的各种各样的方法了。
最后简单说一下Mock测试的使用场景:
1. 真实对象具有不可确定的行为(产生不可预测的结果,如股票行为,如果某种情况发生的概率极其小,可以导致无法测试);
2. 真实对象很难被创建(如request和response对象,和容器相关,我们不能自己new,这个时候就可以mock);
3. 真实对象的某些行为很难触发(如网络错误);
4. 真实对象令程序的运行速度很慢;
4. 真实对象有(或者是)用户界面;
5. 测试需要询问真实对象他是如何被调用的(例如:测试可能需要验证某个回调函数是否被调用了);
6. 等等,读者可以去网上自己找一下mock测试的资料。
作 者: BridgeLi,https://www.bridgeli.cn
原文链接:http://www.bridgeli.cn/archives/253
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。
近期评论