Easymock之初见
2014-01-12 20:54
246 查看
准本工作:
从easymock3版本之后,可以同时mock接口和类,不再需要extention class 包了。使用easymock需要依赖两个包,分别是 Objenesis 和 Cglib
基本概念:
一 . mock和stub的相同点和不同点?
在Manning Junit in Action一书中是这样描述的:
Mocks replace the objects with which your methods
under test collaborate, offering a layer of isolation. In that sense, they’re similar to stubs. But
this is where the similarity ends, because mocks don’t implement any logic: they’re empty shells that provide methods to let the tests control
the behavior of all the business methods of the faked class.
详细的来讲
1.相同点:mock和stub都可以用来对系统(或者将粒度放小为模块,单元)进行隔离。
2.不同点:待补充
Test lifecycle with stubs:
Setup - Prepare object that is being tested and its stubs collaborators.
Exercise - Test the functionality.
Verify state - Use asserts to check object's state.
Teardown - Clean up resources.
Test lifecycle with mocks:
Setup data - Prepare object that is being tested.
Setup expectations - Prepare expectations in mock that is being used by primary object.
Exercise - Test the functionality.
Verify expectations - Verify that correct methods has been invoked in mock.
Verify state - Use asserts to check object's state.
Teardown - Clean up resources.
三.easymock的基本用法
mock一般都有三个阶段,分别是 record,replay,verify。即首先记录mock对象上的操作,然后重演这些操作,最后验证这些操作。
在mock对象调用replay()方法之前是记录mock上的操作阶段。在调用replay()方法之后,才表现出mock对象的行为,并检查这些期望的操作是否真正的被调用。
要获得一个Mock对象,需要三个步骤:
使用接口创建一个mock对象
记录期望的行为(record the expected behavior)
将mock对象切换到replay状态,重演期望的行为
下面使用一个最常用的例子来展示一下mock的基本用法:
实体类User,DAO层接口UserDao,Service层接口UserService,测试对象Service的各个方法是否正确,service所需依赖UserDao,所以需要mock出UserDao对象,用来隔离层,专注于service层的单元测试。类图如下:
![](file:///C:/Users/yameng/AppData/Local/Temp/Wiz/bd7d499d-d571-45ac-b3ee-54a428dee7c8_128_files/95596433-0b06-49e2-a652-be272fda7c90.png)
![](http://img.blog.csdn.net/20140112205339734?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3VueWFtZW5nX25kc2M=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
User对象:
UserDao接口:
UserService类,注意这里为了简单,没有使用接口,而是直接使用类代替
Tip:mock创建的构造方法
createMock(String name, Class claz);
createMock(Class claz);
如果使用第二种,如果测试结果没有预期的,那么会出现如下提示:
java.lang.AssertionError:
Expectation failure on verify:
read(): expected: 7, actual: 0
如果使用第一种,则会出现如下提示:
java.lang.AssertionError:
Expectation failure on verify:
name.read(): expected: 7, actual: 0
红色部分是区别,所以使用第一种更好,标注了提示。
测试代码主要参考:http://easymock.org/EasyMock3_0_Documentation.html
从easymock3版本之后,可以同时mock接口和类,不再需要extention class 包了。使用easymock需要依赖两个包,分别是 Objenesis 和 Cglib
基本概念:
一 . mock和stub的相同点和不同点?
在Manning Junit in Action一书中是这样描述的:
Mocks replace the objects with which your methods
under test collaborate, offering a layer of isolation. In that sense, they’re similar to stubs. But
this is where the similarity ends, because mocks don’t implement any logic: they’re empty shells that provide methods to let the tests control
the behavior of all the business methods of the faked class.
详细的来讲
1.相同点:mock和stub都可以用来对系统(或者将粒度放小为模块,单元)进行隔离。
2.不同点:待补充
Lifecycle
Test lifecycle with stubs:Setup - Prepare object that is being tested and its stubs collaborators.
Exercise - Test the functionality.
Verify state - Use asserts to check object's state.
Teardown - Clean up resources.
Test lifecycle with mocks:
Setup data - Prepare object that is being tested.
Setup expectations - Prepare expectations in mock that is being used by primary object.
Exercise - Test the functionality.
Verify expectations - Verify that correct methods has been invoked in mock.
Verify state - Use asserts to check object's state.
Teardown - Clean up resources.
三.easymock的基本用法
mock一般都有三个阶段,分别是 record,replay,verify。即首先记录mock对象上的操作,然后重演这些操作,最后验证这些操作。
在mock对象调用replay()方法之前是记录mock上的操作阶段。在调用replay()方法之后,才表现出mock对象的行为,并检查这些期望的操作是否真正的被调用。
要获得一个Mock对象,需要三个步骤:
使用接口创建一个mock对象
记录期望的行为(record the expected behavior)
将mock对象切换到replay状态,重演期望的行为
下面使用一个最常用的例子来展示一下mock的基本用法:
实体类User,DAO层接口UserDao,Service层接口UserService,测试对象Service的各个方法是否正确,service所需依赖UserDao,所以需要mock出UserDao对象,用来隔离层,专注于service层的单元测试。类图如下:
![](file:///C:/Users/yameng/AppData/Local/Temp/Wiz/bd7d499d-d571-45ac-b3ee-54a428dee7c8_128_files/95596433-0b06-49e2-a652-be272fda7c90.png)
User对象:
public class User { private int id; private String name; private String age; public User(){} public User(int id,String name,String age){ this.id=id; this.name=name; this.age=age; } //省略getter and setter方法 public void say(){ System.out.println(String.format("%d %s %s ",id,name,age)); } }
UserDao接口:
public interface UserDao { User getUserById(int id); int count(); public String getUserAddress() throws Exception; }
UserService类,注意这里为了简单,没有使用接口,而是直接使用类代替
public class UserService { private UserDao userDao; public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } public String getUserNameById(int id){ String username=userDao.getUserById(id).getName(); return username; } public int count(){ return userDao.count(); } public User getUser(int id){ return userDao.getUserById(id); } public String getUserAddress(int id) throws Exception{ return userDao.getUserAddress(); } }接下来是主要的测试代码:
package easymock; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import static org.easymock.EasyMock.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; /** * Created by superman on 14-1-12. */ public class UserServiceTest { private UserService userService; private UserDao userDaoMock; private User user; @Before public void setUp(){ user=new User(1,"tom","20"); userService=new UserService(); userDaoMock=createMock(UserDao.class); } @Test public void testGetNameById(){ expect(userDaoMock.getUserById(1)).andReturn(user); replay(userDaoMock); userService.setUserDao(userDaoMock); String name=userService.getUserNameById(1); assertEquals("tom",name); verify(userDaoMock); } @Test public void testRepeateCall(){ expect(userDaoMock.getUserById(1)).andReturn(user).times(2); replay(userDaoMock); userService.setUserDao(userDaoMock); String name=userService.getUserNameById(1); name=userService.getUserNameById(1); verify(userDaoMock); assertEquals("tom",name); } @Test public void testReturnValue(){ // expect(userDaoMock.getUserById(1)).andReturn(user); userDaoMock.getUserById(lt(2)); expectLastCall().andReturn(user); replay(userDaoMock); userService.setUserDao(userDaoMock); User user=userService.getUser(1); assertNotNull(user); verify(userDaoMock); } @Test @Ignore public void testException(){ try { expect(userDaoMock.getUserAddress()).andThrow(new Exception("no address attribute")); replay(userDaoMock); userService.setUserDao(userDaoMock); userService.getUserAddress(1); verify(userDaoMock); } catch (Exception e) { e.printStackTrace(); } } }
Tip:mock创建的构造方法
createMock(String name, Class claz);
createMock(Class claz);
如果使用第二种,如果测试结果没有预期的,那么会出现如下提示:
java.lang.AssertionError:
Expectation failure on verify:
read(): expected: 7, actual: 0
如果使用第一种,则会出现如下提示:
java.lang.AssertionError:
Expectation failure on verify:
name.read(): expected: 7, actual: 0
红色部分是区别,所以使用第一种更好,标注了提示。
测试代码主要参考:http://easymock.org/EasyMock3_0_Documentation.html
相关文章推荐
- 文件锁
- Content Providers
- PreparedStatement
- 下拉菜单控制图片
- 杨辉三角形
- Hadoop源码分析之DateNode的目录构成与类继承结构
- 注册nodejs程序为windows服务
- 什么情况下可报名参加广州传智播客.Net就业班培训
- Uncaught TypeError: Object #<Document> has no method 'load'
- USB Phy/ULPI (3-接收模块和传输模块)
- 设计模式之单件模式
- 删除wine菜单残余项
- CvArr、Mat、CvMat、IplImage、BYTE转换(总结而来) .
- 卦圖의 陰陽劃數
- Ogre 中使用OIS的两种模式
- 应用服务器引擎
- ipad iphone model 让 键盘消失
- 基于C#的Access数据库的界面登陆_初体验数据库
- java二维码小试牛刀
- 广州传智播客—牛逼网页设计师的打造所