1 EasyMock - 模拟对象测试

Wu Jun 2019-01-05 17:02:42
12 测试 > 1 EasyMock

easymock官网

一、Mock对象


测试是个好习惯,然而当你想测试自己的代码,而依赖的其他类或方法又还没实现。或者你在实践TDD(测试驱动开发),还没完成你的实现,而又想先测试。该怎么办呢?
简单情况可以手动编写mock类,复杂情况可以借助EasyMock等Mock框架来模拟这些类和方法。
mock 测试只是在无法使用真实类时的聊胜于无,如果能够使用真实的依赖项,就不要使用mock。

二、应用场景


1、要测试的模块依赖于不受控的第三方服务或其它组员未完成的服务。
2、涉及到数据库操作,连接不了数据库或不想测试结果改动到数据库时。
3、模块依赖于spring容器注入其它服务实例,但又不想启动spring容器。
4、测试异常。例如创建模拟网络故障的mock。
……

三、具体使用方法

1、创建mock对象

EasyMock实例化的对象基于接口或者类

EasyMock.createMock(要模拟的成员变量类型);
// ICalcMethod 是一个要mock的对象
ICalcMethod calcMethod = EasyMock.createMock(ICalcMethod.class); 
2、定义mock行为

1)有返回值
expect()方法指定要模拟方法的方法和参数,andReturn()方法定义方法的返回值,times()方法定义mock对象可以调用多少次。

Easymock.expect(模拟成员的某个要模拟的函数).andReturn(期待的返回值)
// 定义mock的期望
EasyMock.expect(calcMethod.calc(Position.BOSS)).andReturn(70000.0).times(2);
EasyMock.expect(calcMethod.calc(Position.PROGRAMMER)).andReturn(50000.0);

2)没返回值
首先模拟成员调用要模拟的函数,然后在后面跟上一句:EasyMock.expectLastCall()

3、模糊参数

有时候要模拟的函数的参数是在程序运行过程中调用的,参数值来自于程序执行结果,这时可以用模糊参数来解决,模糊参数有:
isA、isNull、anyInt等

4、开始测试

在使用mock对象之前需要调用replay()方法使之激活。

EasyMock.replay(模拟成员);
// 激活mock对象
replay(calcMethod); 

四、实例

1、要测试的类

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;
  }
}

该类依赖UserDao,但UserDao可能还没实现,或要靠spring容器来注入
2、测试代码

@Test
public void test() {
  String[] ids = {'1','2','3'};
  List<String> returnNams = Arrays.asList("a,b,c".split(","));
  UserDao userDaoMock = EasyMock.createMock(UserDao.class);//创建模拟成员
  EasyMock.expect(userDaoMock.getNames(ids )).andReturn(returnNams);
      EasyMock.replay(userDaoMock );//重放Mock对象     
  UserServiceImpl userServiceImpl = new UserServiceImpl();
  userServiceImpl .queryNames(ids);//目标类调用目标方法
  EasyMock.verify(userDaoMock );//验证Mock对象       
}
参考

EasyMock 模拟对象测试 使用 EasyMock 更轻松地进行测试 EasyMock jUnit单元测试教程