浅谈EasyMock和PowerMock
来源:互联网 发布:星舞卓萌网络直播 编辑:程序博客网 时间:2024/04/24 17:40
晦涩的EasyMock和PowerMock
又到了周末,作为程序的我深感苦逼,周末无地可去。。。本来心想到了周末可以好好放松放松了,可是真心无伴无钱。此时的困境怎一个囧字了得。嘿嘿!前面是我的一番抱怨了。下面,切入正题吧。
经过一周的学习,算是对EasyMock和PowerMock有了一点点了解。由于我们公司的开发人员在进行单元测试的时候需要使用到的,而且作为新来的毕业生菜鸟。我开始学期了EasyMock和PowerMock。首先我们需要了解什么是EasyMock和PowerMock。
EasyMock:可以从其名称上面入手,简单的Mock。其主要是进行Mock一些接口,当我们在项目中需要使用别人的模块的东西的时候,而我们又不知道别人的有关接口的具体实现。但是我们又需要使用与之有关的结果。此时EasyMock便可以很好的扮演mock的角色。我们可以把相关的接口实现通过EasyMock.createMock(接口.class)来模拟其实现类。
其EasyMock主要有一下几步:
1:模拟一个接口对象:
UserDao udao=EasyMock.createMock(UserDao.class)此时Mock对象处于Record状态
2:设定Mock对象的预期行为和希望得到的结果
/**
* EasyMock.expect()方法后面必定跟着返回值
*/
EasyMock.expect(udao.getById(1001)).andReturn(expectedUser);
3:replay()重置mock对象
EasyMock.replay(udao)
4:进行验证
EasyMock.verify(udao)
EasyMock的使用核心路线主要是:Record------->Replay---------->verify三种状态的切换
以下附上一个完整的代码:
package com.test;
import junit.framework.Assert;
import org.easymock.EasyMock;
import org.junit.Test;
import com.bean.User;
import com.dao.UserDao;
import com.service.impl.UserServiceImpl;
/**
* 使用Mock对象模拟测试的时候,equals(),hashcode(),toString()三个函数无法更改其行为
* @author Clark
* class mock除了以上三个限制外还有final,private方法都不能被mock
* 对于静态方法,easymock也无法mock其行为
*/
public class UserServiceImplTest extends Assert{
@Test
public void testQuery(){
User expectedUser=new User(1001,"clark");
UserDao udao=EasyMock.createMock(UserDao.class);
/**
* EasyMock.expect()方法后面必定跟着返回值
*/
//此处的1001相当于数据库中表的别名。。我们可以随便取名,与前面的1001无关系
EasyMock.expect(udao.getById(1001)).andReturn(expectedUser);
/**
* 如果mock对象的方法是void,则需要使用expectLastCall()方法
*/
// udao.sayHi();
// EasyMock.expectLastCall();
EasyMock.replay(udao);
UserServiceImpl service=new UserServiceImpl();
service.setUserDao(udao);
User u=service.query(1001);
assertNotNull(u);
assertEquals(expectedUser,u);
EasyMock.verify(udao);
}
}
User类package com.bean;
public class User {
public int userId;
public String userName;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public User(int userId, String userName) {
this.userId = userId;
this.userName = userName;
}
public User() {
}
}
Mock的UserDao接口
package com.dao;
import com.bean.User;
public interface UserDao {
public User getById(int userId);
public void sayHi();
}
package com.service;
import com.bean.User;
public interface UserService {
User query(int userId);
}
package com.service.impl;
import com.bean.User;
import com.dao.UserDao;
import com.service.UserService;
public class UserServiceImpl implements UserService{
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public User query(int userId) {
return userDao.getById(userId);
}
public void print(){
userDao.sayHi();
}
}
PowerMock是EasyMock的一个扩展,加入了static,final,private,以及constructor的Mock功能。但是PowerMock并没有继承EasyMock的一些测试功能,所以不能取代EasyMock,而单独使用。在很多时候必须要PowerMock和EasyMock相互结合,以及加上WhiteBox,才能更好实现测试。
1. 必不可少的一步:添加测试运行器@RunWith(PowerMockRunner.class),如果没有添加这个运行器,则使用的是默认的JUnit4.class。在PrepareForTest中加入测试class。@PrepareForTest(测试.class)
Mock构造器函数
public class A{
public void doA(){
new B();
}
}
public class B{
public B(){
System.out.println("can't be here!");
}
}
测试classA中的doA方法:
@RunWith(PowerMockRunner.class)
@PrepareForTest({A.class})
public class ATest {
@Test
public void testdoA() throws Exception {
B mockB = PowerMock.createMock( B.class );
PowerMock.expectNew( B.class ).andReturn(mockB);
A testA = new A();
PowerMock.replayAll();
testA.doA();
PowerMock.verifyAll();
}
}
但是在单元测试testdoA()方法的时候总是会报:
testdoA()
Unrooted Tests
initializationError
心里好纳闷,查了好多资料都没解决。希望哪位高手看到了帮小弟解决一下
3.static
测试static方法的时候必须要加上@PrepareForTest(静态方法.class),否则就会抛出java.lang.IllegalStateException: no last call on a mock available异常。如果有多个class,用{},例如@PrepareForTest({A.class,B.class})
public class A{
public void doA(){
B.doB();
}
}
public class B{
public static String doB() {
return ("can't be here !");
}
}
测试classA中的doA方法:
@RunWith(PowerMockRunner.class)
@PrepareForTest({A.class, B.class})
public class ATest {
@Test
public void testdoA() throws Exception {
PowerMock.mockStatic( B.class );
EasyMock.expect(B.doB()).andReturn("Mocked !");
A testA = new A();
PowerMock.replayAll();
assertEquals("Mock not complete !", testA.doA(), "Mocked !");
PowerMock.verifyAll();
}
}
4.mock类中的Field
一个好的Field应该有getter和setter,但是代码中没有,我们也可以用WhiteBox来Mock掉Field。
public class A{
private String C;
public A(){
C = "Can't be here !";
}
public String doA(){
return C;
}
}
测试A中的doA方法
@RunWith(PowerMockRunner.class)
@PrepareForTest({A.class, B.class})
public class ATest {
@Test
public void testdoA(){
A testA = new A();
String mockC = "Mocked !";
Whitebox.setInternalState( testA, "C", mockC );
assertEquals("Mock not complete !", testA.doA(), "Mocked !");
}
}
- 浅谈EasyMock和PowerMock
- Powermock和Easymock用法总结
- powerMock比easyMock和Mockito更强大
- TestNG和PowerMock EasyMock的结合
- 使用PowerMock和Easymock进行单元测试
- EasyMock PowerMock 的简单使用(with spring Autowired)
- java.lang.VerifyError 在使用PowerMock EasyMock进行单元测试
- 使用Powermock和mockito
- powermock
- powermock
- powermock
- EasyMock
- easyMock
- easymock
- EasyMock
- EasyMock
- easyMock 和 Mockito 的对比
- Junit和EasyMock的使用
- SQL及Oracle和MySQL的数据类型详解
- 如何为切分的窗口使用属性页(从fromview继承)
- UVA 10004 Bicoloring【DFS简单二部图判定】
- iOS随机数
- 【Android】带进度条的WebView
- 浅谈EasyMock和PowerMock
- Hbase 源码分析四 - Get 流程及rpc原理
- Hadoop中一个distcp
- OJ青蛙的约会
- 让Editplus不生成的.bak文件
- 事务的原子性,一致性,隔离性,持久性
- SQL时间格式转化 及其 时间函数
- 在Android 4.2中打开"开发者选项"
- Hbase 源码分析之 Regionserver下的 Get 全流程