EasyMock教程
Mocking是什么?
Mocking是一种在隔离测试一个类的功能。例如,无需数据库连接或属性文件中读取或文件服务器上读取需要测试的功能。 mock对象做实服务的嘲讽。一个mock对象返回对应于传递给它一些虚拟输入无效数据。
EasyMock
EasyMock便于无缝地创建模拟对象。它使用Java反射,以创造为给定接口的模拟对象。模拟对象是什么,只不过是代理的实际实现。考虑如:股票服务的情况下,它返回一个股票价格的详细信息。在开发过程中,实际的库存服务不能被用于获得实时数据。因此,我们需要一个虚拟的股票实施服务。简易模拟可以很容易理解顾名思义这样。
EasyMock的好处
- 不用手写 - 没有必要通过自己编写的模拟对象。
- 重构安全 - 重构接口方法的名称或重新排序的参数不会破坏测试代码在运行时创建。
- 返回值支持 - 支持返回值。
- 异常支持 - 支持例外/异常。
- 命令检查支持 - 支持检查命令方法调用。
- 注释支持 - 支持使用注解创建。
考虑下面的代码片段。
package com.yiibai.mock;
import java.util.ArrayList;
import java.util.List;
import org.easymock.EasyMock;
public class PortfolioTester {
public static void main(String[] args){
//Create a portfolio object which is to be tested
Portfolio portfolio = new Portfolio();
//Creates a list of stocks to be added to the portfolio
List<Stock> stocks = new ArrayList<Stock>();
Stock googleStock = new Stock("1","Google", 10);
Stock microsoftStock = new Stock("2","Microsoft",100);
stocks.add(googleStock);
stocks.add(microsoftStock);
//Create the mock object of stock service
StockService stockServiceMock = EasyMock.createMock(StockService.class);
//mock the behavior of stock service to return the value of various stocks
EasyMock.expect(stockServiceMock.getPrice(googleStock)).andReturn(50.00);
EasyMock.expect(stockServiceMock.getPrice(microsoftStock)).andReturn(1000.00);
EasyMock.replay(stockServiceMock);
//add stocks to the portfolio
portfolio.setStocks(stocks);
//set the stockService to the portfolio
portfolio.setStockService(stockServiceMock);
double marketValue = portfolio.getMarketValue();
//verify the market value to be 10*50.00 + 100* 1000.00 = 500.00 + 100000.00 = 100500
System.out.println("Market value of the portfolio: "+ marketValue);
}
}
让我们来了解上述程序的重要概念。完整的代码在第一个应用。
- Portfolio - 进行股票名单,并获得用股票价格和股票数量计算的市场价值的对象。
- Stock - 携带一只股票的详细信息,如它的id,名称,数量等的对象
- StockService - 股票的服务接口,其功能是返回一个股票的当前价格。
- EasyMock.createMock(...) - EasyMock股票创建了服务的模拟
- EasyMock.expect(...).andReturn(...) - 模拟实现StockService接口用getPrice方法。对于googleStock,回到50.00的价格。
- EasyMock.replay(...) - EasyMock准备模拟对象,以便它可以被用于测试目的。
- portfolio.setStocks(...) - 现在的投资组合包含了两只股票列表。
- portfolio.setStockService(...) - 分配的StockService模拟对象来组合。
- portfolio.getMarketValue() - 基于使用的模拟股票服务公司的股票投资组合回报的市场价值。
EasyMock环境安装 - EasyMock教程
EasyMock是Java框架,所以第一个要求是要在机器安装JDK。
系统要求
JDK | 1.5 或以上. |
内存 | 没有最低要求 |
硬盘空间 | 没有最低要求 |
操作系统 | 没有最低要求 |
第1步 - 验证Java安装在机器
现在,打开控制台并执行以下java命令。
OS | 任务 | 命令 |
Windows | 打开命令控制台 | c:\> java -version |
Linux | 打开命令终端 | $ java -version |
Mac | 打开终端 | machine:~ joseph$ java -version |
让我们来为所有的操作系统验证输出:
Windows
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b07)
Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing)
Linux
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b07)
Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing)
Mac
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b07)
Java HotSpot(TM)64-Bit Server VM (build 17.0-b17, mixed mode, sharing)
如果还没有安装Java,安装Java软件开发工具包(SDK)可从http://www.oracle.com/technetwork/java/javase/downloads/index.htmll 下载最新版本。我们假设Java1.6.0_21 作为本教程的安装版本。
第2步:设置JAVA环境
设置 JAVA_HOME 环境变量指向到安装在机器上的Java的基本目录的位置。例如
OS | 输出 |
Windows | 设置环境变量 JAVA_HOME 到 C:\Program Files\Java\jdk1.6.0_21 |
Linux | export JAVA_HOME=/usr/local/java-current |
Mac | export JAVA_HOME=/Library/Java/Home |
添加 Java编译器位置到系统路径。
OS | 输出 |
Windows | Append the string ;C:\Program Files\Java\jdk1.6.0_21\bin to the end of the system variable, Path. |
Linux | export PATH=$PATH:$JAVA_HOME/bin/ |
Mac | not required |
用 java -version 命令验证如上所述Java安装。
第3步:下载EasyMock
从 http://sourceforge.net/projects/easymock/files/EasyMock/3.2/easymock-3.2.zip/download 下载EasyMock的zip文件的最新版本。在写这篇教程的时候,下载的是 easymock-3.2.zip 并将其复制到C:\>EasyMock 文件夹。
OS | 归档文件名称 |
Windows | easymock-3.2.zip |
Linux | easymock-3.2.zip |
Mac | easymock-3.2.zip |
第4步:下载EasyMock的依赖包
从https://github.com/cglib/cglib/releases下载cglib的jar文件的最新版本。在写这篇教程的时候,我下载的是 cglib-3.1.jar 并将其复制到 C:\> EasyMock 文件夹。
从http://objenesis.org/download.htmll下载objenesis.zip文件的最新版本。在写这篇教程的时候,我下载objenesis-2.1-bin.zip 并将其复制到C:\> EasyMock文件夹。提取objenesis-2.1.jar到C:\> EasyMock文件夹
第5步:设置EasyMock的环境
设置EasyMock_HOME环境变量指向的地方EasyMock的和依赖的jar都存储在您计算机上的基本目录的位置。假设,我们已经提取了easymock-3.2.jar, cglib-3.1.jar 和objenesis-2.1.jar在各种操作系统上EasyMock的文件夹,如下所示。
OS | 输出 |
Windows | 设置环境变量EasyMock_HOME to C:\EasyMock |
Linux | export EasyMock_HOME=/usr/local/EasyMock |
Mac | export EasyMock_HOME=/Library/EasyMock |
第5步:设置CLASSPATH变量
设置CLASSPATH环境变量指向了EasyMock和依赖的jar位置。假设,我们已经存储了easymock-3.2.jar, cglib-3.1.jar 和objenesis-2.1.jar i在EasyMock的文件夹,在各种操作系统上,如下所示。
OS | 输出 |
Windows | 设置环境变量CLASSPATH to %CLASSPATH%;%EasyMock_HOME%\easymock-3.2.jar;%EasyMock_HOME%\cglib-3.1.jar;%EasyMock_HOME%\objenesis-2.1.jar;.; |
Linux | export CLASSPATH=$CLASSPATH:$EasyMock_HOME/easymock-3.2.jar:$EasyMock_HOME/cglib-3.1.jar:$EasyMock_HOME/objenesis-2.1.jar:. |
Mac | export CLASSPATH=$CLASSPATH:$EasyMock_HOME/easymock-3.2.jar:$EasyMock_HOME/cglib-3.1.jar:$EasyMock_HOME/objenesis-2.1.jar:. |
第6步:下载Junit的归档
从https://github.com/junit-team/junit/wiki/Download-and-Install下载JUnit的jar文件的最新版本。在写这篇教程的时候,我下载的是Junit-4.11.jar,hamcrest-core-1.2.1.jar ,并复制它们到C:\> JUnit文件夹中。
OS | 归档名称 |
Windows | junit4.11.jar, hamcrest-core-1.2.1.jar |
Linux | junit4.11.jar, hamcrest-core-1.2.1.jar |
Mac | junit4.11.jar, hamcrest-core-1.2.1.jar |
第7步:设置JUnit的环境
设置JUNIT_HOME环境变量指向JUNIT的jar都存储在您计算机上的基本目录的位置。假设,我们已经存储junit4.11.jar, hamcrest-core-1.2.1.jar 在JUnit文件夹在各种操作系统上,如下所示。
OS | 输出 |
Windows | 设置环境变量 JUNIT_HOME to C:\JUNIT |
Linux | export JUNIT_HOME=/usr/local/JUNIT |
Mac | export JUNIT_HOME=/Library/JUNIT |
第8步:设置CLASSPATH变量
设置CLASSPATH环境变量指向了JUnit的jar位置。假设,我们已经存储junit4.10.jar在JUnit夹在各种操作系统上,如下所示。
OS | 输出 |
Windows | 设置环境变量 CLASSPATH 为 %CLASSPATH%;%JUNIT_HOME%\junit4.11.jar;%JUNIT_HOME%\hamcrest-core-1.2.1.jar;.; |
Linux | export CLASSPATH=$CLASSPATH:$JUNIT_HOME/junit4.11.jar:$JUNIT_HOME/hamcrest-core-1.2.1.jar:. |
Mac | export CLASSPATH=$CLASSPATH:$JUNIT_HOME/junit4.11.jar:$JUNIT_HOME/hamcrest-core-1.2.1.jar:. |
EasyMock异常处理 - EasyMock教程
EasyMock提供了一个功能,用以模拟抛出异常,所以异常处理可以进行测试。
//add the behavior to throw exception
EasyMock.expect(calcService.add(10.0,20.0)).andThrow(new RuntimeException("Add operation not implemented"));
在这里,我们添加了一个异常子句模仿对象。 MathApplication利用使用calcService其Add方法和模型将抛出RuntimeException异常时调用calcService.add()方法。
示例
创建一个接口CalculatorService,其目的是提供各种计算相关的功能。
CalculatorService.java
public interface CalculatorService {
public double add(double input1, double input2);
public double subtract(double input1, double input2);
public double multiply(double input1, double input2);
public double divide(double input1, double input2);
}
创建一个Java类用来表示MathApplication。
MathApplication.java
public class MathApplication {
private CalculatorService calcService;
public void setCalculatorService(CalculatorService calcService){
this.calcService = calcService;
}
public double add(double input1, double input2){
return calcService.add(input1, input2);
}
public double subtract(double input1, double input2){
return calcService.subtract(input1, input2);
}
public double multiply(double input1, double input2){
return calcService.multiply(input1, input2);
}
public double divide(double input1, double input2){
return calcService.divide(input1, input2);
}
}
让我们来测试MathApplication类,通过它注入CalculatorService作一个模拟。Mock将由EasyMock创建。
MathApplicationTester.java
import org.easymock.EasyMock;
import org.easymock.EasyMockRunner;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(EasyMockRunner.class)
public class MathApplicationTester {
//@TestSubject annotation is used to identify class which is going to use the
//mock object
@TestSubject
MathApplication mathApplication = new MathApplication();
//@Mock annotation is used to create the mock object to be injected
@Mock
CalculatorService calcService;
@Test(expected = RuntimeException.class)
public void testAdd(){
//add the behavior to throw exception
EasyMock.expect(calcService.add(10.0,20.0)).andThrow(new RuntimeException("Add operation not implemented"));
//activate the mock
EasyMock.replay(calcService);
//test the add functionality
Assert.assertEquals(mathApplication.add(10.0, 20.0),30.0,0);
//verify call to calcService is made or not
EasyMock.verify(calcService);
}
}
创建一个Java类在文件夹 C:\ > EasyMock_WORKSPACE 执行测试用例
TestRunner.java
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(MathApplicationTester.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
验证结果
使用javac编译如下类
C:\EasyMock_WORKSPACE>javac MathApplicationTester.java
现在运行测试运行看结果
C:\EasyMock_WORKSPACE>java TestRunner
验证输出
true
EasyMock JUnit集成 - EasyMock教程
在本章中,我们将集成JUnit和EasyMock在一起。对于JUnit,请参阅JUnit教程。我们使用计算器服务的例子。目的是创建一个数学应用,它使用CalculatorService做加,减,除运算操作。我们将使用EasyMock来模拟虚拟实现CalculatorService。此外,使用注解广泛展示注解支持JUnit和EasyMock。
以下是所采取的步骤。
创建一个接口CalculatorService,其目的是提供各种计算相关的功能。
CalculatorService.java
public interface CalculatorService {
public double add(double input1, double input2);
public double subtract(double input1, double input2);
public double multiply(double input1, double input2);
public double divide(double input1, double input2);
}
创建一个Java类来表示MathApplication.
MathApplication.java
public class MathApplication {
private CalculatorService calcService;
public void setCalculatorService(CalculatorService calcService){
this.calcService = calcService;
}
public double add(double input1, double input2){
return calcService.add(input1, input2);
}
public double subtract(double input1, double input2){
return calcService.subtract(input1, input2);
}
public double multiply(double input1, double input2){
return calcService.multiply(input1, input2);
}
public double divide(double input1, double input2){
return calcService.divide(input1, input2);
}
}
让我们来测试MathApplication类,通过它注入CalculatorService作一个模拟。Mock将由EasyMock创建。
MathApplicationTester.java
import org.easymock.EasyMock;
import org.easymock.EasyMockRunner;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(EasyMockRunner.class)
public class MathApplicationTester {
//@TestSubject annotation is used to identify class which is going to use the
//mock object
@TestSubject
MathApplication mathApplication = new MathApplication();
//@Mock annotation is used to create the mock object to be injected
@Mock
CalculatorService calcService;
@Test
public void testAdd(){
//add the behavior of calc service to add two numbers
EasyMock.expect(calcService.add(10.0,20.0)).andReturn(30.00);
//activate the mock
EasyMock.replay(calcService);
//test the add functionality
Assert.assertEquals(mathApplication.add(10.0, 20.0),30.0,0);
}
}
创建一个Java类在文件夹 C:\ > EasyMock_WORKSPACE 执行测试用例
TestRunner.java
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(MathApplicationTester.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
验证结果
编译使用javac编译如下的类
C:\EasyMock_WORKSPACE>javac CalculatorService.java MathApplication.java MathApplicationTester.java TestRunner.java
现在运行测试运行看结果
C:\EasyMock_WORKSPACE>java TestRunner
验证输出
true
EasyMock添加行为 - EasyMock教程
EasyMock使用expect()方法或expectLassCall()方法添加一个功能,一个模拟对象。请看下面的代码片段。
//add the behavior of calc service to add two numbers
EasyMock.expect(calcService.add(10.0,20.0)).andReturn(30.00);
这里,我们已经指示EasyMock,行为添加10和20到calcService的添加方法并作为其结果,到返回值30.00
在这个时间点上,模拟简单记录的行为,但它本身不作为一个模拟对象。调用回放后,按预期工作。
//add the behavior of calc service to add two numbers
EasyMock.expect(calcService.add(10.0,20.0)).andReturn(30.00);
//activate the mock
//EasyMock.replay(calcService);
EasyMock验证行为 - EasyMock教程
EasyMock提供了一个检查被使用或不使用verify()方法,请看下面的代码片段。
//activate the mock
EasyMock.replay(calcService);
//test the add functionality
Assert.assertEquals(mathApplication.add(10.0, 20.0),30.0,0);
//verify call to calcService is made or not
EasyMock.verify(calcService);
EasyMock期望调用 - EasyMock教程
EasyMock提供,可以在特定的方法来的调用的数目的特别检查。假设MathApplication使用其的任意方法,其中CalculatorService.serviceUsed()方法表示CalculatorService的用于获得所需要的操作结果之前调用CalculatorService.serviceUsed()方法,只有一次。 MathApplication应该不能够调用CalculatorService.serviceUsed()一次以上。
//add the behavior of calc service to add two numbers and serviceUsed.
EasyMock.expect(calcService.add(10.0,20.0)).andReturn(30.00);
calcService.serviceUsed();
//limit the method call to 1, no less and no more calls are allowed
EasyMock.expectLastCall().times(1);
创建CalculatorService的界面如下。
CalculatorService.java
public interface CalculatorService {
public double add(double input1, double input2);
public double subtract(double input1, double input2);
public double multiply(double input1, double input2);
public double divide(double input1, double input2);
public void serviceUsed();
}
calcService.serviceUsed()被调用一次例子
calcService.serviceUsed()调用两次例子
无需调用calcService.serviceUsed()示例
EasyMock改变调用 - EasyMock教程
EasyMock提供很多的方法来改变预期的调用计数。
- times(int min, int max) - 最小值和最大值之间的预期调用。
- atLeastOnce() - 预期至少有一个调用。
- anyTimes() - 预期调用的数量不受限制。
EasyMock异常处理 - EasyMock教程
EasyMock提供了一个功能,用以模拟抛出异常,所以异常处理可以进行测试。
//add the behavior to throw exception
EasyMock.expect(calcService.add(10.0,20.0)).andThrow(new RuntimeException("Add operation not implemented"));
在这里,我们添加了一个异常子句模仿对象。 MathApplication利用使用calcService其Add方法和模型将抛出RuntimeException异常时调用calcService.add()方法。
示例
创建一个接口CalculatorService,其目的是提供各种计算相关的功能。
CalculatorService.java
public interface CalculatorService {
public double add(double input1, double input2);
public double subtract(double input1, double input2);
public double multiply(double input1, double input2);
public double divide(double input1, double input2);
}
创建一个Java类用来表示MathApplication。
MathApplication.java
public class MathApplication {
private CalculatorService calcService;
public void setCalculatorService(CalculatorService calcService){
this.calcService = calcService;
}
public double add(double input1, double input2){
return calcService.add(input1, input2);
}
public double subtract(double input1, double input2){
return calcService.subtract(input1, input2);
}
public double multiply(double input1, double input2){
return calcService.multiply(input1, input2);
}
public double divide(double input1, double input2){
return calcService.divide(input1, input2);
}
}
让我们来测试MathApplication类,通过它注入CalculatorService作一个模拟。Mock将由EasyMock创建。
MathApplicationTester.java
import org.easymock.EasyMock;
import org.easymock.EasyMockRunner;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(EasyMockRunner.class)
public class MathApplicationTester {
//@TestSubject annotation is used to identify class which is going to use the
//mock object
@TestSubject
MathApplication mathApplication = new MathApplication();
//@Mock annotation is used to create the mock object to be injected
@Mock
CalculatorService calcService;
@Test(expected = RuntimeException.class)
public void testAdd(){
//add the behavior to throw exception
EasyMock.expect(calcService.add(10.0,20.0)).andThrow(new RuntimeException("Add operation not implemented"));
//activate the mock
EasyMock.replay(calcService);
//test the add functionality
Assert.assertEquals(mathApplication.add(10.0, 20.0),30.0,0);
//verify call to calcService is made or not
EasyMock.verify(calcService);
}
}
创建一个Java类在文件夹 C:\ > EasyMock_WORKSPACE 执行测试用例
TestRunner.java
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(MathApplicationTester.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
验证结果
使用javac编译如下类
C:\EasyMock_WORKSPACE>javac MathApplicationTester.java
现在运行测试运行看结果
C:\EasyMock_WORKSPACE>java TestRunner
验证输出
true
EasyMock createMock - EasyMock教程
到目前为止,我们已经使用注解来创建Mocks。 EasyMock提供了各种方法来创建模拟对象。 EasyMock.createMock()创建的模拟,但没有理会方法的顺序调用模拟会在作出其行动的适当时机。
语法
calcService = EasyMock.createMock(CalculatorService.class);
示例
创建一个接口CalculatorService,其目的是提供各种计算相关的功能。
CalculatorService.java
public interface CalculatorService {
public double add(double input1, double input2);
public double subtract(double input1, double input2);
public double multiply(double input1, double input2);
public double divide(double input1, double input2);
}
创建一个Java类用来表示MathApplication。
MathApplication.java
public class MathApplication {
private CalculatorService calcService;
public void setCalculatorService(CalculatorService calcService){
this.calcService = calcService;
}
public double add(double input1, double input2){
return calcService.add(input1, input2);
}
public double subtract(double input1, double input2){
return calcService.subtract(input1, input2);
}
public double multiply(double input1, double input2){
return calcService.multiply(input1, input2);
}
public double divide(double input1, double input2){
return calcService.divide(input1, input2);
}
}
让我们来测试MathApplication类,通过它注入CalculatorService作一个模拟。Mock将由EasyMock创建。
在这里,我们已经添加了两个模拟方法调用,add()和subtract()来模拟对象,通过expect()。但在测试过程中,我们调用Add()方法前调用subtract()。当我们创建模拟对象使用EasyMock.createMock(),以便执行方法。
MathApplicationTester.java
import org.easymock.EasyMock;
import org.easymock.EasyMockRunner;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(EasyMockRunner.class)
public class MathApplicationTester {
private MathApplication mathApplication;
private CalculatorService calcService;
@Before
public void setUp(){
mathApplication = new MathApplication();
calcService = EasyMock.createMock(CalculatorService.class);
mathApplication.setCalculatorService(calcService);
}
@Test
public void testAddAndSubstract(){
//add the behavior to add numbers
EasyMock.expect(calcService.add(20.0,10.0)).andReturn(30.0);
//subtract the behavior to subtract numbers
EasyMock.expect(calcService.subtract(20.0,10.0)).andReturn(10.0);
//activate the mock
EasyMock.replay(calcService);
//test the substract functionality
Assert.assertEquals(mathApplication.subtract(20.0, 10.0),10.0,0);
//test the add functionality
Assert.assertEquals(mathApplication.add(20.0, 10.0),30.0,0);
//verify call to calcService is made or not
EasyMock.verify(calcService);
}
}
创建一个Java类在文件夹 C:\ > EasyMock_WORKSPACE 执行测试用例
TestRunner.java
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(MathApplicationTester.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
验证结果
使用javac编译如下类
C:\EasyMock_WORKSPACE>javac MathApplicationTester.java
现在运行测试运行看结果
C:\EasyMock_WORKSPACE>java TestRunner
验证输出
true
EasyMock createStrictMock - EasyMock教程
EasyMock.createStrictMock()创建的模拟,也需要关心的方法的顺序调用模拟会在作出其行动的适当时机。
语法
calcService = EasyMock.createStrictMock(CalculatorService.class);
示例
创建一个接口CalculatorService,其目的是提供各种计算相关的功能。
CalculatorService.java
public interface CalculatorService {
public double add(double input1, double input2);
public double subtract(double input1, double input2);
public double multiply(double input1, double input2);
public double divide(double input1, double input2);
}
创建一个Java类用来表示MathApplication。
MathApplication.java
public class MathApplication {
private CalculatorService calcService;
public void setCalculatorService(CalculatorService calcService){
this.calcService = calcService;
}
public double add(double input1, double input2){
return calcService.add(input1, input2);
}
public double subtract(double input1, double input2){
return calcService.subtract(input1, input2);
}
public double multiply(double input1, double input2){
return calcService.multiply(input1, input2);
}
public double divide(double input1, double input2){
return calcService.divide(input1, input2);
}
}
让我们来测试MathApplication类,通过它注入CalculatorService作一个模拟。Mock将由EasyMock创建。
在这里,我们已经添加了两个模拟方法调用,add()和subtract()来模拟对象,通过expect()。但在测试过程中,我们调用Add()方法前调用subtract()。当我们创建一个使用EasyMock.createStrictMock()的模拟对象,以便执行方法。
MathApplicationTester.java
import org.easymock.EasyMock;
import org.easymock.EasyMockRunner;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(EasyMockRunner.class)
public class MathApplicationTester {
private MathApplication mathApplication;
private CalculatorService calcService;
@Before
public void setUp(){
mathApplication = new MathApplication();
calcService = EasyMock.createStrictMock(CalculatorService.class);
mathApplication.setCalculatorService(calcService);
}
@Test
public void testAddAndSubstract(){
//add the behavior to add numbers
EasyMock.expect(calcService.add(20.0,10.0)).andReturn(30.0);
//subtract the behavior to subtract numbers
EasyMock.expect(calcService.subtract(20.0,10.0)).andReturn(10.0);
//activate the mock
EasyMock.replay(calcService);
//test the substract functionality
Assert.assertEquals(mathApplication.subtract(20.0, 10.0),10.0,0);
//test the add functionality
Assert.assertEquals(mathApplication.add(20.0, 10.0),30.0,0);
//verify call to calcService is made or not
EasyMock.verify(calcService);
}
}
创建一个Java类在文件夹 C:\ > EasyMock_WORKSPACE 执行测试用例
TestRunner.java
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(MathApplicationTester.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
验证结果
使用javac编译如下类
C:\EasyMock_WORKSPACE>javac MathApplicationTester.java
现在运行测试运行看结果
C:\EasyMock_WORKSPACE>java TestRunner
验证输出
testAddAndSubstract(com.yiibai.mock.MathApplicationTester):
Unexpected method call CalculatorService.subtract(20.0, 10.0):
CalculatorService.add(20.0, 10.0): expected: 1, actual: 0
false
EasyMock createNiceMock - EasyMock教程
EasyMock.createNiceMock()创建了模拟,并设置模拟的每个方法的默认实现。如果使用EasyMock.createMock(),然后模拟方法调用将抛出断言错误。
语法
calcService = EasyMock.createNiceMock(CalculatorService.class);
示例
创建一个接口CalculatorService,其目的是提供各种计算相关的功能。
CalculatorService.java
public interface CalculatorService {
public double add(double input1, double input2);
public double subtract(double input1, double input2);
public double multiply(double input1, double input2);
public double divide(double input1, double input2);
}
创建一个Java类用来表示MathApplication。
MathApplication.java
public class MathApplication {
private CalculatorService calcService;
public void setCalculatorService(CalculatorService calcService){
this.calcService = calcService;
}
public double add(double input1, double input2){
return calcService.add(input1, input2);
}
public double subtract(double input1, double input2){
return calcService.subtract(input1, input2);
}
public double multiply(double input1, double input2){
return calcService.multiply(input1, input2);
}
public double divide(double input1, double input2){
return calcService.divide(input1, input2);
}
}
让我们来测试MathApplication类,通过它注入CalculatorService作一个模拟。Mock将由EasyMock创建。
在这里,我们已经增加了一个模拟的方法调用,add()通过expect()。但在测试过程中,我们称之为substract()等方法。当创建一个使用EasyMock.createNiceMock()模拟对象,用缺省值缺省实现是可用的。
MathApplicationTester.java
import org.easymock.EasyMock;
import org.easymock.EasyMockRunner;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(EasyMockRunner.class)
public class MathApplicationTester {
private MathApplication mathApplication;
private CalculatorService calcService;
@Before
public void setUp(){
mathApplication = new MathApplication();
calcService = EasyMock.createNiceMock(CalculatorService.class);
mathApplication.setCalculatorService(calcService);
}
@Test
public void testCalcService(){
//add the behavior to add numbers
EasyMock.expect(calcService.add(20.0,10.0)).andReturn(30.0);
//activate the mock
EasyMock.replay(calcService);
//test the add functionality
Assert.assertEquals(mathApplication.add(20.0, 10.0),30.0,0);
//test the substract functionality
Assert.assertEquals(mathApplication.subtract(20.0, 10.0),0.0,0);
//test the multiply functionality
Assert.assertEquals(mathApplication.divide(20.0, 10.0),0.0,0);
//test the divide functionality
Assert.assertEquals(mathApplication.multiply(20.0, 10.0),0.0,0);
//verify call to calcService is made or not
EasyMock.verify(calcService);
}
}
创建一个Java类在文件夹 C:\ > EasyMock_WORKSPACE 执行测试用例
TestRunner.java
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(MathApplicationTester.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
验证结果
使用javac编译如下类
C:\EasyMock_WORKSPACE>javac MathApplicationTester.java
现在运行测试运行看结果
C:\EasyMock_WORKSPACE>java TestRunner
验证输出
true
EasyMock EasyMockSupport - EasyMock教程
EasyMockSupport是Utiliy或辅助类的测试类。它提供了以下功能
- replayAll() - 都记录在一个批次中创建模拟。
- verifyAll() - 验证所有模拟操作于一个批次。
- resetAll() - 将所有模拟操作于一个批次。
示例
创建一个接口CalculatorService,其目的是提供各种计算相关的功能。
CalculatorService.java
public interface CalculatorService {
public double add(double input1, double input2);
public double subtract(double input1, double input2);
public double multiply(double input1, double input2);
public double divide(double input1, double input2);
}
创建一个Java类用来表示MathApplication。
MathApplication.java
public class MathApplication {
private CalculatorService calcService;
public void setCalculatorService(CalculatorService calcService){
this.calcService = calcService;
}
public double add(double input1, double input2){
return calcService.add(input1, input2);
}
public double subtract(double input1, double input2){
return calcService.subtract(input1, input2);
}
public double multiply(double input1, double input2){
return calcService.multiply(input1, input2);
}
public double divide(double input1, double input2){
return calcService.divide(input1, input2);
}
}
让我们来测试MathApplication类,通过它注入CalculatorService作一个模拟。Mock将由EasyMock创建。
MathApplicationTester.java
import org.easymock.EasyMockRunner;
import org.easymock.EasyMockSupport;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(EasyMockRunner.class)
public class MathApplicationTester extends EasyMockSupport {
private MathApplication mathApplication1;
private MathApplication mathApplication2;
private CalculatorService calcService1;
private CalculatorService calcService2;
@Before
public void setUp(){
mathApplication1 = new MathApplication();
mathApplication2 = new MathApplication();
calcService1 = createNiceMock(CalculatorService.class);
calcService2 = createNiceMock(CalculatorService.class);
mathApplication1.setCalculatorService(calcService1);
mathApplication2.setCalculatorService(calcService2);
}
@Test
public void testCalcService(){
//activate all mocks
replayAll();
//test the add functionality
Assert.assertEquals(mathApplication1.add(20.0, 10.0),0.0,0);
//test the substract functionality
Assert.assertEquals(mathApplication1.subtract(20.0, 10.0),0.0,0);
//test the multiply functionality
Assert.assertEquals(mathApplication1.divide(20.0, 10.0),0.0,0);
//test the divide functionality
Assert.assertEquals(mathApplication1.multiply(20.0, 10.0),0.0,0);
//test the add functionality
Assert.assertEquals(mathApplication2.add(20.0, 10.0),0.0,0);
//test the substract functionality
Assert.assertEquals(mathApplication2.subtract(20.0, 10.0),0.0,0);
//test the multiply functionality
Assert.assertEquals(mathApplication2.divide(20.0, 10.0),0.0,0);
//test the divide functionality
Assert.assertEquals(mathApplication2.multiply(20.0, 10.0),0.0,0);
//verify all the mocks
verifyAll();
}
}
创建一个Java类在文件夹 C:\ > EasyMock_WORKSPACE 执行测试用例
TestRunner.java
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(MathApplicationTester.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
验证结果
使用javac编译如下类
C:\EasyMock_WORKSPACE>javac MathApplicationTester.java
现在运行测试运行看结果
C:\EasyMock_WORKSPACE>java TestRunner
验证输出
true