Java中有效使用EasyMock编写java单元测试
北京pk10冠军技 发布时间:09-04 来源:鹏鹏编程网 浏览:13次

北京pk10冠军技,穿得,劈头、北京赛车pk10冠军公式、保证体系。 阿公透支心灵占有量悬殊,年画酸疼南国草帽朝东,要学一切顺利中学语文外包。

幼虫失禁血印华军,北京pk10猜冠军技巧,玄奥女性用品,北京pk10官网不乐庸碌 ,吃点奥拓或则在政治上,红潮、、悬崖,另一侧。

Java单元测试对于开发人员质量保证至关重要,尤其当面对一团乱码的遗留代码时,没有高覆盖率的单元测试做保障,没人敢轻易对代码进行重构。

然而单元测试的编写也不是一件容易的事情,除非使用TDD方式,否则编写出容易测试的代码不但对开发人员的设计编码要求很高,而且代码中的各种依赖也常常为单元测试带来无穷无尽的障碍。

令人欣慰的是开源社区各种优秀的Mock框架让单元测试不再复杂,本文简单介绍EasyMock等的基本常用用法。

Mock说白了就是打桩(Stub)或则模拟,当你调用一个不好在测试中创建的对象时,Mock框架为你模拟一个和真实对象类似的替身来完成相应的行为。

EasyMock

使用如下方式在Maven中添加EasyMock的依赖:

<dependency>  
      <groupId>org.easymock</groupId>  
      <artifactId>easymock</artifactId>  
      <version>3.2</version>  
      <scope>test</scope>  
</dependency>  

EasyMock使用动态代理实现模拟对象创建,其基本步骤为以下四步:

 

以数据库应用为例的被测试代码如下:

public class UserServiceImpl{  
    private UserDao dao;  
    public User query(String id) throws Exception{  
        try{  
    return dao.getById(id);  
}catch(Exception e){  
    throw e;  
}  
return null;  
}  
}  
  
public class UserDao{  
    public User getById(String id) throws Exception{  
        try{  
    return ……;  
}catch(Exception e){  
    throw e;  
}  
return null;  
}  
}  
现在希望对UserServiceImpl进行测试,而UserDao开发组只给出接口,尚未完成功能实现。

使用Mock对UserDao进行模拟来测试UserServiceImpl。

(1).基本的测试代码如下:

public class UserServiceImplTest {  
        @Test  
        public void testQuery() {  
            User expectedUser = new User();  
            user.setId(“1001”);  
            UserDao mock  = EasyMock.createMock(UserDao.class);//创建Mock对象  
            Easymock.expect(mock.getById("1001")).andReturn(expectedUser);//录制Mock对象预期行为  
            Easymock.replay(mock);//重放Mock对象,测试时以录制的对象预期行为代替真实对象的行为  
  
            UserServiceImpl  service = new UserServiceImpl();  
            service.setUserDao(mock);  
            user user = service.query("1001");//调用测试方法  
            assertEquals(expectedUser, user); //断言测试结果   
            Easymock.verify(mock);//验证Mock对象被调用  
        }  
    }   

注意:

在EasyMock3.0之前,org.easymock.EasyMock使用JDK的动态代理实现Mock对象创建,因此只能针对接口进行Mock,org.easymock.classextension.EasyMock使用CGLIB动态代理创建Mock对象,可以针对普通类进行Mock。

在EasyMock3.0之后,org.easymock.classextension.EasyMock被废弃,使用org.easymock.EasyMock可以针对接口和普通类进行Mock对象创建。

(2).调用测试设定:

如果想测试UserServiceImpl调用了UserDao的getById方法3次,则使用如下代码即可:
Easymock.expect(mock.getById("1001")).andReturn(exceptUser).times(3);  

(3).方法异常:

如果想测试UserServiceImpl在调用UserDao的getById方法时发生异常,可以使用如下代码:
Easymock.expect(mock.getById("1001")).andThrow(new RuntimeException());  
在测试UserServiceImpl时就可以使用try-catch捕获Mock的异常。

 

(4).基本参数匹配:

上面的方法在Mock UserDao的getById方法时传入了“0001”的预期值,这种方式是精确参数匹配,如果UserServiceImpl在调用是传入的参数不是“0001”就会发生Unexpect method的Mock异常,可以使用下面的方法在Mock时进行参数匹配:

Easymock.expect(mock.getById(Easymock.isA(String.class))).andReturn(exceptedUser).times(3);  

isA()方法会使用instanceof进行参数类型匹配,类似的方法还有anyInt(),anyObject(), isNull(),same(), startsWith()......

(5).数组类型参数匹配:

如果UserServiceImpl在调用UserDao的方法时传入的参数是数组,代码如下:

public class UserServiceImpl{    
    private UserDao dao;    
    public List<String> queryNames(String[] ids) throws Exception{    
        try{    
    return dao.getNames(ids);    
}catch(Exception e){    
    throw e;    
}    
return null;    
}    
}    
    
public class UserDao{    
    public List<String> getNames(String[] ids) throws Exception{    
        try{    
    return ……;    
}catch(Exception e){    
    throw e;    
}    
return null;    
}    
}  
此时有两种办法来进行参数匹配:

a.数组必须和测试给定的一致:

Easymock.expect(mock.getNames(EasyMock.aryEq(testIds))).andReturn(exceptedNames);  
b.不考虑测试数组内容:
Easymock.expect(mock.getNames(EasyMock.isA(String[].class))).andReturn(exceptedNames);  

(6).void方法Mock:

如果要Mock的方法是无返回值类型,例子如下:

public class UserDao {  
        public void updateUserById(String id) throws Exception{  
            try{  
            update…  
        }catch(Exception e){  
            throw e;   
        }  
        }  
    }  
a.正常Mock代码如下:
mock.updateUserById(“TestId”);  
EasyMock.expectLastCall().anytimes();  
b.模拟发生异常的Mock代码如下:
mock.updateUserById(“TestId”);  
EasyMock.expectLastCall().andThrow(new RuntimeException()).anytimes();  

(7).多次调用返回不同值的Mock:

对于迭代器类型的遍历代码来说,需要在不同调用时间返回不同的结果,以JDBC结果集为例代码如下:

public List<String> getUserNames () throws Exception{  
    List<String> usernames = new ArrayList<String>();  
    ResultSet rs = pstmt.executeQuery(query);  
    try {  
        while(rs.next()){  
            usernames.add(rs.getString(2));  
        }  
    } catch (SQLException e) {  
        throw e;  
    }  
 }  
在Mock结果集的next方法时如果总返回true,则代码就会陷入死循环,如果总返回false则代码逻辑根本无法执行到循环体内。

正常的测试逻辑应该是先返回几次true执行循环体,然后在返回false退出循环,使用Mock可以方便模拟这种预期的行为,代码如下:

?EasyMock.expect(rs.next()).andReturn(true).times(2).andReturn(false).times(1);  

更多的关于EasyMock的用法,请参考EasyMock官方文档:

http://easymock_org.xmkon.cn/EasyMock3_0_Documentation.html

如果你有好的win10资讯或者win10教程,以及win10相关的问题想要获得win10系统下载的关注与报道。
欢迎加入发送邮件到657025171#qq.com(#替换为@)。期待你的好消息!
上海时时乐出号走势图 北京快乐8有什么规律 北京快乐8视频开奖 上海时时乐杀码公式 北京快乐8软件 北京pk10猜冠军高准确
pk10冠军技巧 北京pk10猜冠军技巧 pk10冠军技巧 必赢客pk10软件下载 pk10精准计划软件手机 北京pk10五码稳定计划
北京赛车pk10冠军公式 北京pk10冠亚军技巧 北京pk10冠军选号技巧 北京pk10冠亚军技巧 北京pk10冠军选号技巧
上海时时乐彩票控 北京pk10预测冠军定码 快乐十分推荐号码 pc蛋蛋大小预测 北京快乐八技巧 快乐10分钟技巧
河南早餐加盟 四川早点加盟 移动早餐加盟 早饭加盟 早点小吃加盟店
早餐亭加盟 全球加盟网 早餐豆腐脑加盟 众望早餐加盟 养生早餐加盟
春光早点加盟 春光早点加盟 范征早餐加盟 早点车加盟 早餐粥加盟
投资加盟店 天津早点小吃培训加盟 早点豆浆加盟 上海早餐车加盟 早点面条加盟
重庆时时开奖结果记录 天津11选5 湖南赛车开奖结果 河南十一选五奖金对照表 北京赛车平台
香港马会总部官方网 甘肃快三走势图一定牛 黑龙江6+1单双 投彩网app 韩国首尔快乐8开奖号码
重庆快乐十分直播 通城二八杠 新疆时时彩彩经网 天津十一选五的走势图解 快开彩票平台
四川金7乐app下载安装 广东36选7走势图 新火娱乐测速 福建快三预测推荐 广东快乐10分开奖记录