EasyMock - 快速指南


EasyMock - 概述

什么是模拟?

模拟是一种单独测试类功能的方法。模拟不需要数据库连接或属性文件读取或文件服务器读取来测试功能。模拟对象对真实服务进行模拟。模拟对象返回与传递给它的某些虚拟输入相对应的虚拟数据。

易模拟

EasyMock 有助于无缝创建模拟对象。它使用 Java Reflection 为给定接口创建模拟对象。模拟对象只不过是实际实现的代理。考虑一个返回股票价格详细信息的股票服务的情况。在开发过程中,无法使用实际的库存服务来获取实时数据。所以我们需要一个库存服务的虚拟实现。正如其名称所示,EasyMock 可以非常轻松地完成相同的任务。

EasyMock 的好处

  • 无需手写- 无需自己编写模拟对象。

  • 重构安全- 重命名接口方法名称或重新排序参数不会破坏测试代码,因为模拟是在运行时创建的。

  • 返回值支持- 支持返回值。

  • 异常支持- 支持异常。

  • 顺序检查支持- 支持检查方法调用的顺序。

  • 注释支持- 支持使用注释创建模拟。

例子

考虑以下代码片段。

package com.tutorialspoint.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);
   }
}

让我们了解一下上面程序的重要概念。完整的代码可以在 第一个应用程序一章中找到。

  • 投资组合- 携带股票列表并使用股票价格和股票数量计算市场价值的对象。

  • Stock - 携带股票详细信息的对象,例如其 ID、名称、数量等。

  • StockService - 股票服务返回股票的当前价格。

  • EasyMock.createMock(...) - EasyMock 创建了库存服务的模拟。

  • EasyMock.expect(...).andReturn(...) - stockService 接口的 getPrice 方法的模拟实现。对于 googleStock,返回 50.00 作为价格。

  • EasyMock.replay(...) - EasyMock 准备 Mock 对象以使其可用于测试。

  • portfolio.setStocks(...) - 投资组合现在包含两只股票的列表。

  • folio.setStockService(...) - 将 stockService 模拟对象分配给投资组合。

  • folio.getMarketValue() - 投资组合使用模拟股票服务返回基于其股票的市场价值。

EasyMock - 环境设置

本章将带您完成在基于 Windows 和 Linux 的系统上设置 EasyMock 的过程。EasyMock 可以轻松安装并与您当前的 Java 环境集成,只需几个简单的步骤,无需任何复杂的设置过程。安装时需要用户管理。

系统要求

JDK Java SE 2 JDK 1.5 或更高版本
记忆 1 GB RAM(推荐)
磁盘空间 无最低要求
操作系统版本 Windows XP或以上、Linux

现在让我们继续安装 EasyMock 的步骤。

第 1 步:验证您的 Java 安装

首先,您需要在系统上安装 Java 软件开发工具包 (SDK)。要验证这一点,请根据您正在使用的平台执行这两个命令中的任意一个。

如果 Java 安装已正确完成,那么它将显示 Java 安装的当前版本和规范。下表给出了示例输出。

平台 命令 样本输出
Windows

打开命令控制台并输入:

\>java –版本

java 版本“11.0.11”2021-04-20 LTS

Java(TM) SE 运行时环境 18.9(内部版本 11.0.11+9-LTS-194)

Java HotSpot(TM) 64 位服务器 VM 18.9(内部版本 11.0.11+9-LTS-194,混合模式)

Linux

打开命令终端并输入:

$java –版本

java 版本“11.0.11”2021-04-20 LTS

打开JDK运行时环境18.9(内部版本11.0.11+9-LTS-194)

打开JDK 64位服务器VM(内部版本11.0.11+9-LTS-194,混合模式)

第 2 步:设置 Java 环境

将环境变量 JAVA_HOME 设置为指向计算机上安装 Java 的基本目录位置。例如,

先生。 平台及描述
1

Windows

将 JAVA_HOME 设置为 C:\ProgramFiles\java\jdk11.0.11

2

Linux

导出 JAVA_HOME = /usr/local/java-current

将 Java 编译器位置的完整路径附加到系统路径。

先生。 平台及描述
1

Windows

将字符串“C:\Program Files\Java\jdk11.0.11\bin”附加到系统变量 PATH 的末尾。

2

Linux

导出路径=$PATH:$JAVA_HOME/bin/

如上所述,从命令提示符处执行命令java -version 。

第三步:安装EasyMock库

从https://easymock.org/下载最新版本的 EasyMock ,并将其内容解压缩到一个文件夹,从该文件夹中可以将所需的库链接到您的 Java 程序。让我们假设这些文件收集在 C 驱动器上的文件夹中。

将所需jar的完整路径添加到 CLASSPATH 中,如下所示。

先生。 平台及描述
1

Windows

将以下字符串附加到用户变量的末尾

类路径 -

C:\easymock\easymock-4.3.jar;

2

Linux

导出 CLASSPATH = $CLASSPATH:

/usr/share/easymock\easymock-4.3.tar:

第 4 步:下载 JUnit 存档

从Github下载最新版本的 JUnit jar 文件。将文件夹保存在位置 C:\>Junit。

操作系统 档案名称
Windows junit4.13.2.jar、hamcrest-core-1.3.jar
Linux junit4.13.2.jar、hamcrest-core-1.3.jar

第5步:设置JUnit环境

将JUNIT_HOME环境变量设置为指向计算机上存储 JUnit jar 的基本目录位置。下表显示了如何在不同操作系统上设置此环境变量,假设我们已将 junit4.13.2.jar 和 hamcrest-core-1.3.jar 存储在 C:\>Junit 中。

操作系统 输出
Windows 将环境变量 JUNIT_HOME 设置为 C:\JUNIT
Linux 导出 JUNIT_HOME=/usr/local/JUNIT

第 6 步:设置 CLASSPATH 变量

将 CLASSPATH 环境变量设置为指向 JUNIT jar 位置。下表显示了它在不同操作系统上的完成方式。

操作系统 输出
Windows 设置环境变量CLASSPATH为%CLASSPATH%;%JUNIT_HOME%\junit4.13.2.jar;%JUNIT_HOME%\hamcrest-core-1.3.jar;。
Linux 导出 CLASSPATH=$CLASSPATH:$JUNIT_HOME/junit4.13.2.jar:$JUNIT_HOME/hamcrest-core-1.3.jar:。

EasyMock - 第一个应用程序

在详细介绍 EasyMock 框架之前,让我们先看看一个正在运行的应用程序。在此示例中,我们创建了 Stock Service 的模拟来获取某些股票的虚拟价格,并对名为 Portfolio 的 Java 类进行了单元测试。

下面将逐步讨论该过程。

例子

第 1 步:创建一个 JAVA 类来表示 Stock

文件:Stock.java

public class Stock {
   private String stockId;
   private String name;	
   private int quantity;

   public Stock(String stockId, String name, int quantity){
      this.stockId = stockId;
      this.name = name;		
      this.quantity = quantity;		
   }
   public String getStockId() {
      return stockId;
   }
   public void setStockId(String stockId) {
      this.stockId = stockId;
   }
   public int getQuantity() {
      return quantity;
   }
   public String getTicker() {
      return name;
   }
}

步骤2:创建一个接口StockService来获取股票的价格。

文件:StockService.java

public interface StockService {
   public double getPrice(Stock stock);
}

步骤 3:创建一个投资组合类来代表任何客户的投资组合。

文件:Portfolio.java

import java.util.List;

public class Portfolio {
   private StockService stockService;
   private List<Stock> stocks;

   public StockService getStockService() {
      return stockService;
   }
   public void setStockService(StockService stockService) {
      this.stockService = stockService;
   }
   public List<Stock> getStocks() {
      return stocks;
   }
   public void setStocks(List<Stock> stocks) {
      this.stocks = stocks;
   }
   public double getMarketValue(){
      double marketValue = 0.0;
      for(Stock stock:stocks){
         marketValue += stockService.getPrice(stock) * stock.getQuantity();
      }
      return marketValue;
   }
}

第 4 步:测试 Portfolio 类

让我们通过注入 stockservice 的模拟来测试 Portfolio 类。模拟将由 EasyMock 创建。

文件:PortfolioTester.java

import java.util.ArrayList;
import java.util.List;
import org.easymock.EasyMock;

public class PortfolioTester {
   Portfolio portfolio;	
   StockService stockService;

   public static void main(String[] args){
      PortfolioTester tester = new PortfolioTester();
      tester.setUp();
      System.out.println(tester.testMarketValue()?"pass":"fail");
   }
   public void setUp(){
      //Create a portfolio object which is to be tested		
      portfolio = new Portfolio();		
      
      //Create the mock object of stock service
      stockService = EasyMock.createMock(StockService.class);		
      
      //set the stockService to the portfolio
      portfolio.setStockService(stockService);
   }
   public boolean testMarketValue(){
      //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);

      //add stocks to the portfolio
      portfolio.setStocks(stocks);

      // mock the behavior of stock service to return the value of various stocks
      EasyMock.expect(stockService.getPrice(googleStock)).andReturn(50.00);
      EasyMock.expect(stockService.getPrice(microsoftStock)).andReturn(1000.00);		

      // activate the mock
      EasyMock.replay(stockService);		

      double marketValue = portfolio.getMarketValue();		
      return marketValue == 100500.0;
   }
}

第 5 步:验证结果

使用javac编译器编译类,如下所示 -

C:\EasyMock_WORKSPACE>javac Stock.java StockService.java Portfolio.java PortfolioTester.java

现在运行 PortfolioTester 查看结果 -

C:\EasyMock_WORKSPACE>java PortfolioTester

输出

验证输出

pass

EasyMock - JUnit 集成

在本章中,我们将学习如何将 JUnit 和 EasyMock 集成在一起。在这里,我们将创建一个数学应用程序,它使用 CalculatorService 来执行基本的数学运算,例如加法、减法、乘法和除法。我们将使用 EasyMock 来模拟 CalculatorService 的虚拟实现。此外,我们还广泛使用注释来展示它们与 JUnit 和 EasyMock 的兼容性。

例子

下面将逐步讨论该过程。

步骤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);
}

第2步:创建一个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);
   }
}

步骤 3:测试 MathApplication 类

让我们通过向其中注入calculatorService 的模拟来测试MathApplication 类。模拟将由 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);
   }
}

步骤4:创建一个类来执行测试用例。

在C:\> EasyMock_WORKSPACE中创建一个名为 TestRunner 的 java 类文件来执行测试用例。

文件: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());
   }
}  	

第 5 步:验证结果

使用javac编译器编译类,如下所示 -

C:\EasyMock_WORKSPACE>javac CalculatorService.java MathApplication.java MathApplicationTester.java TestRunner.java

现在运行测试运行程序来查看结果 -

C:\EasyMock_WORKSPACE>java TestRunner

输出

验证输出。

true

要了解有关 JUnit 的更多信息,请参阅 Tutorials Point 上的 JUnit 教程。

EasyMock - 添加Behave

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 向 calcService 的 add 方法提供将 10 和 20 相加的Behave,结果返回值 30.00。

此时,Mock 只是记录了Behave,但它并没有作为模拟对象工作。调用重播后,它按预期工作。

//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.Replay() 的示例

步骤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);
}

第2步:创建一个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);
   }
}

步骤 3:测试 MathApplication 类

让我们通过向其中注入calculatorService 的模拟来测试MathApplication 类。模拟将由 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 the 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);
   }
}

步骤 4:执行测试用例

在C:\>EasyMock_WORKSPACE中创建一个名为 TestRunner 的 java 类文件来执行测试用例。

文件: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());
   }
}  	

第 5 步:验证结果

使用javac编译器编译类,如下所示 -

C:\EasyMock_WORKSPACE>javac Calculator Service.java Math Application.java Math Application Tester.java Test Runner.java

现在运行测试运行程序来查看结果 -

C:\EasyMock_WORKSPACE>java TestRunner

输出

验证输出。

testAdd(MathApplicationTester): expected:<0.0> but was:<30.0>
false

EasyMock.Replay() 示例

步骤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);
}

步骤2:创建一个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);
   }
}

步骤 3:测试 MathApplication 类

让我们通过向其中注入calculatorService 的模拟来测试MathApplication 类。模拟将由 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);
   }
}

步骤 4:执行测试用例

在C:\>EasyMock_WORKSPACE中创建一个名为 TestRunner 的 java 类文件来执行测试用例。

文件: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());
   }
}  	

第 5 步:验证结果

使用javac编译器编译类,如下所示 -

C:\EasyMock_WORKSPACE>javac Calculator Service.java Math Application.java Math Application Tester.java Test Runner.java

现在运行测试运行程序以查看结果。

C:\EasyMock_WORKSPACE>java TestRunner

输出

验证输出。

true

EasyMock - 验证Behave

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.Verify() 的示例

步骤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);
}

第2步:创建一个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);
      return 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);
   }
}

步骤 3:测试 MathApplication 类

让我们通过向其中注入calculatorService 的模拟来测试MathApplication 类。模拟将由 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);

      //verify call to calcService is made or not
      //EasyMock.verify(calcService);
   }
}

步骤 4:执行测试用例

在C:\> EasyMock_WORKSPACE中创建一个名为 TestRunner 的 java 类文件来执行测试用例。

文件: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());
   }
}  	

第 5 步:验证结果

使用javac编译器编译类,如下所示 -

C:\EasyMock_WORKSPACE>javac Calculator Service.java Math Application.java Math Application Tester.java Test Runner.java

现在运行测试运行程序以查看结果。

C:\EasyMock_WORKSPACE>java TestRunner

输出

验证输出。

true

EasyMock.Verify() 示例

步骤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);
}

第2步:创建一个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);
      return 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);
   }
}

步骤 3:测试 MathApplication 类

让我们通过向其中注入calculatorService 的模拟来测试MathApplication 类。模拟将由 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);

      //verify call to calcService is made or not
      EasyMock.verify(calcService);
   }
}

步骤 4:执行测试用例

在C:\> EasyMock_WORKSPACE中创建一个名为 TestRunner 的 java 类文件来执行测试用例。

文件: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());
   }
}  	

第 5 步:验证结果

使用javac编译器编译类,如下所示 -

C:\EasyMock_WORKSPACE>javac Calculator Service.java Math Application.java Math Application Tester.java Test Runner.java

现在运行测试运行程序来查看结果 -

C:\EasyMock_WORKSPACE>java TestRunner

输出

验证输出。

testAdd(MathApplicationTester): 
   Expectation failure on verify:
      CalculatorService.add(10.0, 20.0): expected: 1, actual: 0
false

EasyMock - 期待来电

EasyMock 提供了对可以对特定方法进行的调用次数的特殊检查。假设 MathApplication 应该只调用 CalculatorService.serviceUsed() 方法一次,那么它不应该能够多次调用 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() 的示例

步骤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();
}

第2步:创建一个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){		
      calcService.serviceUsed();
      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);
   }
}

步骤 3:测试 MathApplication 类

让我们通过向其中注入calculatorService 的模拟来测试MathApplication 类。模拟将由 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);
      calcService.serviceUsed();
      EasyMock.expectLastCall().times(1);
      
      //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);
   }
}

步骤 4:执行测试用例

在C:\> EasyMock_WORKSPACE中创建一个名为 TestRunner 的 java 类文件来执行测试用例。

文件: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());
   }
}  	

第 5 步:验证结果

使用javac编译器编译类,如下所示 -

C:\EasyMock_WORKSPACE>javac Calculator Service.java Math Application.java Math Application Tester.java Test Runner.java

现在运行测试运行程序来查看结果 -

C:\EasyMock_WORKSPACE>java TestRunner

输出

验证输出。

true

calcService.serviceUsed() 调用两次的示例

步骤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();
}

步骤2:创建一个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){		
      calcService.serviceUsed();
      calcService.serviceUsed();
      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);
   }
}

步骤 3:测试 MathApplication 类

让我们通过向其中注入calculatorService 的模拟来测试MathApplication 类。模拟将由 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);
      calcService.serviceUsed();
      EasyMock.expectLastCall().times(1);
      
      //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);
   }
}

步骤 4:执行测试用例

在C:\> EasyMock_WORKSPACE中创建一个名为 TestRunner 的 java 类文件来执行测试用例。

文件: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()); 
   }
}  	

第 5 步:验证结果

使用javac编译器编译类,如下所示 -

C:\EasyMock_WORKSPACE>javac CalculatorService.java MathApplication.java MathApplicationTester.java TestRunner.java

现在运行测试运行程序来查看结果 -

C:\EasyMock_WORKSPACE>java TestRunner

输出

验证输出。

testAdd(com.tutorialspoint.mock.MathApplicationTester):  
   Unexpected method call CalculatorService.serviceUsed():
      CalculatorService.add(10.0, 20.0): expected: 1, actual: 0
      CalculatorService.serviceUsed(): expected: 1, actual: 2
false

不调用 calcService.serviceUsed() 的示例

步骤1:创建接口Calculator Service,提供数学函数

文件: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();
}

第2步:创建一个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);
   }
}

步骤 3:测试 MathApplication 类

让我们通过向其中注入calculatorService 的模拟来测试MathApplication 类。模拟将由 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);
      calcService.serviceUsed();
      EasyMock.expectLastCall().times(1);
      
      //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);
   }
}

步骤 4:执行测试用例

在C:\> EasyMock_WORKSPACE中创建一个名为 TestRunner 的 java 类文件来执行测试用例。

文件: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());
   }
}  	

第 5 步:验证结果

使用javac编译器编译类,如下所示 -

C:\EasyMock_WORKSPACE>javac Calculator Service.java Math Application.java Math Application Tester.java Test Runner.java

现在运行测试运行程序来查看结果 -

C:\EasyMock_WORKSPACE>java TestRunner

输出

验证输出。

testAdd(com.tutorialspoint.mock.MathApplicationTester): 
   Expectation failure on verify:
      CalculatorService.serviceUsed(): expected: 1, actual: 0
false

EasyMock - 不同的调用

EasyMock 提供了以下附加方法来改变预期的调用计数。

  • times (int min, int max) - 期望在最小和最大调用之间。

  • atLeastOnce () - 期望至少一次调用。

  • anyTimes () - 期望调用次数不受限制。

时间示例(最小,最大)

步骤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();
}

第2步:创建一个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){
      calcService.serviceUsed();
      calcService.serviceUsed();
      calcService.serviceUsed();   
      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);
   }
}

步骤 3:测试 MathApplication 类

让我们通过向其中注入calculatorService 的模拟来测试MathApplication 类。模拟将由 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);
      calcService.serviceUsed();
      EasyMock.expectLastCall().times(1,3);
      
      //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);
   }
}

步骤 4:执行测试用例

在C:\> EasyMock_WORKSPACE中创建一个名为 TestRunner 的 java 类文件来执行测试用例

文件: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());
   }
}  	

第 5 步:验证结果

使用javac编译器编译类,如下所示 -

C:\EasyMock_WORKSPACE>javac Calculator Service.java Math Application.java Math Application Tester.java Test Runner.java

现在运行测试运行程序来查看结果 -

C:\EasyMock_WORKSPACE>java TestRunner

输出

验证输出。

true

atLeastOnce 示例

步骤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();
}

第2步:创建一个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){
      calcService.serviceUsed();
      calcService.serviceUsed(); 
      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);
   }
}

步骤 3:测试 MathApplication 类

让我们通过向其中注入calculatorService 的模拟来测试MathApplication 类。模拟将由 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);
      calcService.serviceUsed();
      EasyMock.expectLastCall().atLeastOnce();
      
      //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);
   }
}

步骤 4:执行测试用例

在C:\> EasyMock_WORKSPACE中创建一个名为 TestRunner 的 java 类文件来执行测试用例。

文件: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());
   }
}  	

第 5 步:验证结果

使用javac编译器编译类,如下所示 -

C:\EasyMock_WORKSPACE>javac Calculator Service.java Math Application.java Math Application Tester.java Test Runner.java

现在运行测试运行程序来查看结果 -

C:\EasyMock_WORKSPACE>java TestRunner

输出

验证输出。

true

任何时间的示例

步骤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();
}

第2步:创建一个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){
      calcService.serviceUsed();
      calcService.serviceUsed(); 
      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);
   }
}

步骤 3:测试 MathApplication 类

让我们通过向其中注入calculatorService 的模拟来测试MathApplication 类。模拟将由 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);
      calcService.serviceUsed();
      EasyMock.expectLastCall().anyTimes();
      
      //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);
   }
}

步骤 4:执行测试用例

在C:\> EasyMock_WORKSPACE中创建一个名为 TestRunner 的 java 类文件来执行测试用例。

文件: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());
   }
}  	

第 5 步:验证结果

使用javac编译器编译类,如下所示 -

C:\EasyMock_WORKSPACE>javac Calculator Service.java Math Application.java Math Application Tester.java Test Runner.java

现在运行测试运行程序来查看结果 -

C:\EasyMock_WORKSPACE>java TestRunner

输出

验证输出。

true

EasyMock - 异常处理

EasyMock 为模拟提供了抛出异常的功能,因此可以测试异常处理。看一下下面的代码片段。

//add the behavior to throw exception

EasyMock.expect(calc Service.add(10.0,20.0)).and Throw(new Runtime Exception("Add operation not implemented"));

这里我们向模拟对象添加了一个异常子句。MathApplication 通过其 add 方法来使用 calcService,并且每当调用 calcService.add() 方法时,模拟都会抛出 RuntimeException。

例子

步骤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);
}

第2步:创建一个JAVA类来表示MathApplication

文件:MathApplication.java

public class MathApplication {
   private CalculatorService calcService;
   public void setCalculatorService(CalculatorService calcService){
      this.calcService = calcService;
   }
   public double add(double