环境搭建:
EasyMock is available in theMaven central repository. Just add the following dependency to your pom.xml:
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.0</version>
<scope>test</scope>
</dependency>
注意:Spring配置action的作用域需要为prototypeeasyMock是通过context.getBean(‘actionId’)的方式获得对象的
使用用EasyMock的一般步骤:
1.创建一个mock对象 :
org.easymock.classextension.EasyMock被用来mock抽象类(abstract)和具体类
org.easymock.EasyMock被用来mock接口(interface)
HttpServletRequest request =EasyMock.createMock(HttpServletRequest.class);
2.设置此对象的某个方法的返回值
/**
* 设定 Mock 对象的预期行为和输出
*/
EasyMock.expect(request.getParameter("id")).andReturn("1").once();
PrintWriter pw = new PrintWriter(System.out,true);
//没返回值的
response.setContentType("text/html;charset=UTF-8");
//有返回值的
EasyMock.expect(response.getWriter()).andReturn(pw).anyTimes();
注意:必须手工设置被mock的方法的访问次数
once()
antyTimes()
times(int)
建议:在设置方法调用次数的时候,虽然你可以调用anyTimes(),但是最好明确你要调用多少次如:once()、
times(2),这样做的话显的比较严谨。
如果mock的方法没有返回值,可以这么做:
response.setContentType("text/html;charset=UTF-8");
对于被mock的方法参数,也可以不必指定具体的值:
EasyMock.expect(request.getParameter((String)EasyMock.anyObject())).andReturn("trilogy").once();
如果你想让被mock的方法返回一个异常,前提是被mock的方法会抛出异常,你可以这么做:
EasyMock.expect(input.read()).andThrow(newIOException("Mocked IOException")).once();
你还可以根据调用顺序来mock同一个方法:
EasyMock.expect(request.getParameter("userName")).andReturn("trilogy").once();
EasyMock.expect(request.getParameter("userName")).andReturn(null).once();
当第一次执行request.getParameter("userName")的时候,返回“trilogy”
当第二次执行request.getParameter("userName")的时候,返回null
3.保存被mock的对象
EasyMock.replay(a);
4.在被mock的对象被应用之后,最好验证一下我们所设置的mock对象是不是按我们预期运行。
EasyMock.verify(a);
总结:
EasyMock是一个相当方便的mock工具,可以为我们的测试工作提供极大的便利,特别是在测试web层或者数据库访问的时候。
注意:在程序中获得request的方式就得是getHttpServletRequest();而不能通过ServletActionContext.getRequest()方式获得,但在
同意数据会存入数据库
(1)Object方法的限制
我们都知道java是一个单根继承体系,Object是所有类的基类。在Object类上有几个基本的方法,easymock是不能改变其行为的:equals(), hashCode()和toString()。
即对于easymock创建的mock对象,其equals(), hashCode()和toString()三个方法的行为时已经固定了点,不能通过Easymock.expect()来指定这三个方法的行为,即使这三个方法是接口定义的一部分。
(2)class mock的限制
相对于interface mock,classmock下easymock限制更多,除了上面谈到的equals(), hashCode()和toString()三个方法外,还有以下限制:
1. final 方法不能被mock
2. private 方法不能对mock
(3) 静态方法
对于静态方法,easymock也无法mock其行为。
由于这个限制,当被测试类中有静态方法调用时,典型如单例方法调用,lookup方式的依赖查找,easymock就会力不从心。从这个角度上,推荐尽量使用IOC 控制反转/ DI依赖注入的方式来实现依赖的获取,而不要使用lookup的主动查找方式。
实际开发中,当发现有因为静态方法的限制从而导致easymock无法mock我们期望的行为,造成测试案例"不好写",“写不下去”时,请换个角度思考:为什么要用静态方法?可不可以改成注入?
(4) 解决的方法
如果由于某些原因必须使用静态方法或者定制final, private方法的行为,则可以考虑搭配其他mock框架来完成功能。
以静态方法方法为例,一个典型的使用范例是:使用jmockit来定制静态方法的行为,指定其返回easymock创建的mock对象,然后使用easymock的标准方式定制这个mock对象的行为。
EasyMock的录制:
CreateMock() 默认的录制
CreateNiceMock()友好录制主要是返回一些默认的值,不检测是否执行过
CreateStrictMock()严格录制,方法的执行顺序
createMockBuilder()可以为选择某个方法录制而不录制其他方法