Mockito-quick-guide

提供:Dev Guides
移動先:案内検索

Mockito-概要

モッキングとは何ですか?

モッキングは、クラスの機能を単独でテストする方法です。 モックでは、機能をテストするためにデータベース接続やプロパティファイルの読み取りやファイルサーバーの読み取りは必要ありません。 モックオブジェクトは、実際のサービスのモックを行います。 モックオブジェクトは、渡されたダミー入力に対応するダミーデータを返します。

モッキート

Mockitoは、モックオブジェクトのシームレスな作成を容易にします。 Java Reflectionを使用して、特定のインターフェイスのモックオブジェクトを作成します。 モックオブジェクトは、実際の実装のプロキシにすぎません。

株式の価格の詳細を返す株式サービスの場合を考えてみましょう。 開発中、実際のストックサービスを使用してリアルタイムデータを取得することはできません。 そのため、ストックサービスのダミー実装が必要です。 Mockitoは、その名前が示すように、同じことを非常に簡単に行うことができます。

Mockitoの利点

  • 手書きなし-自分でモックオブジェクトを書く必要はありません。
  • リファクタリングセーフ-実行時にMocksが作成されるため、インターフェイスメソッドの名前を変更したり、パラメーターを並べ替えたりしても、テストコードが破損することはありません。
  • 戻り値のサポート-戻り値をサポートします。
  • 例外サポート-例外をサポートします。
  • 順序チェックのサポート-メソッド呼び出しの順序のチェックをサポートします。
  • 注釈のサポート-注釈を使用したモックの作成をサポートします。

次のコードスニペットを考えてください。

package com.finddevguides.mock;

import java.util.ArrayList;
import java.util.List;

import static org.mockito.Mockito.*;

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 = mock(StockService.class);

     //mock the behavior of stock service to return the value of various stocks
      when(stockServiceMock.getPrice(googleStock)).thenReturn(50.00);
      when(stockServiceMock.getPrice(microsoftStock)).thenReturn(1000.00);

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

上記のプログラムの重要な概念を理解しましょう。 完全なコードは、 _ First Application_ の章で入手できます。

  • ポートフォリオ-株式のリストを保持し、株価と在庫量を使用して計算された市場価値を取得するオブジェクト。
  • ストック-ID、名前、数量など、ストックの詳細を保持するオブジェクト。
  • StockService -株式サービスは、株式の現在の価格を返します。
  • * mock(…​)*-Mockitoはストックサービスのモックを作成しました。
  • * when(…​)。thenReturn(…​)*-stockServiceインターフェイスのgetPriceメソッドのモック実装。 googleStockの場合、価格として50.00を返します。
  • * portfolio.setStocks(…​)*-ポートフォリオには2つの銘柄のリストが含まれるようになりました。
  • * portfolio.setStockService(…​)*-stockService Mockオブジェクトをポートフォリオに割り当てます。
  • * portfolio.getMarketValue()*-ポートフォリオは、模擬株式サービスを使用して、株式に基づいて市場価値を返します。

Mockito-環境設定

MockitoはJavaのフレームワークであるため、最初の要件はJDKをマシンにインストールすることです。

システム要件

JDK 1.5 or above.
Memory no minimum requirement.
Disk Space no minimum requirement.
Operating System no minimum requirement.

ステップ1-マシンでのJavaインストールの検証

コンソールを開き、次の java コマンドを実行します。

OS Task Command
Windows Open Command Console c:\> java -version
Linux Open Command Terminal $ java -version
Mac Open Terminal machine:> joseph$ java -version

すべてのオペレーティングシステムの出力を確認しましょう-

OS Output
Windows

java version "1.6.0_21"

Java(TM)SEランタイム環境(ビルド1.6.0_21-b07)

Java HotSpot(TM)Client VM(ビルド17.0-b17、混合モード、共有)

Linux

java version "1.6.0_21"

Java(TM)SEランタイム環境(ビルド1.6.0_21-b07)

Java HotSpot(TM)Client VM(ビルド17.0-b17、混合モード、共有)

Mac

java version "1.6.0_21"

Java(TM)SEランタイム環境(ビルド1.6.0_21-b07)

Java HotSpot(TM)64ビットサーバーVM(ビルド17.0-b17、混合モード、共有)

Javaをインストールしていない場合、Java Software Development Kit(SDK)をインストールするにはhttp://www.oracle.com/technetwork/java/javase/downloads/indexl [ここをクリック]

このチュートリアルでは、システムにJava 1.6.0_21がインストールされていると想定しています。

ステップ2-JAVA環境の設定

*JAVA_HOME* 環境変数を設定して、Javaがマシンにインストールされているベースディレクトリの場所を指すようにします。 例えば、
OS Output
Windows Set the environment variable JAVA_HOME to 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 Output
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-Mockito-Allアーカイブのダウンロード

MavenリポジトリからMockitoの最新バージョンをダウンロードするにはhttp://mvnrepository.com/artifact/org.mockito/mockito-all/2.0.2-beta [ここをクリックしてください。]

Cドライブにjarファイルを保存します。C:\> Mockitoのようにします。

OS Archive name
Windows mockito-all-2.0.2-beta.jar
Linux mockito-all-2.0.2-beta.jar
Mac mockito-all-2.0.2-beta.jar

ステップ4-Mockito環境の設定

*Mockito_HOME* 環境変数を設定して、マシン上のMockitoおよび依存関係jarが保存されているベースディレクトリの場所を指定します。 次の表は、mockito-all-2.0.2-beta.jarをC:\> Mockitoフォルダーに抽出したと仮定して、異なるオペレーティングシステムで環境変数を設定する方法を示しています。
OS Output
Windows Set the environment variable Mockito_HOME to C:\Mockito
Linux export Mockito_HOME=/usr/local/Mockito
Mac export Mockito_HOME=/Library/Mockito

ステップ5-CLASSPATH変数の設定

*CLASSPATH* 環境変数を設定して、Mockito jarが保存されている場所を指すようにします。 次の表は、さまざまなオペレーティングシステムでCLASSPATH変数を設定する方法を示しています。
OS Output
Windows Set the environment variable CLASSPATH to %CLASSPATH%;%Mockito_HOME%\mockito-all-2.0.2-beta.jar;.;
Linux export CLASSPATH=$CLASSPATH:$Mockito_HOME/mockito-all-2.0.2-beta.jar:.
Mac export CLASSPATH=$CLASSPATH:$Mockito_HOME/mockito-all-2.0.2-beta.jar:.

ステップ6-JUnitアーカイブのダウンロード

GithubからJUnit jarファイルの最新バージョンをダウンロードします。 C:\> Junitの場所にフォルダーを保存します。

OS Archive name
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が格納されているベースディレクトリの場所を指すようにします。 次の表は、C:\> Junitにjunit4.11.jarおよびhamcrest-core-1.2.1.jarを保存したと仮定して、異なるオペレーティングシステムでこの環境変数を設定する方法を示しています。
OS Output
Windows Set the environment variable JUNIT_HOME to C:\JUNIT
Linux export JUNIT_HOME=/usr/local/JUNIT
Mac export JUNIT_HOME=/Library/JUNIT

ステップ8-CLASSPATH変数の設定

JUNIT jarの場所を指すようにCLASSPATH環境変数を設定します。 次の表は、さまざまなオペレーティングシステムでどのように実行されるかを示しています。

OS Output
Windows Set the environment variable CLASSPATH to %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:.

Mockito-最初のアプリケーション

Mockitoフレームワークの詳細に入る前に、実際に動作しているアプリケーションを見てみましょう。 この例では、一部の株式のダミー価格を取得するためにストックサービスのモックを作成し、Portfolioという名前のJavaクラスを単体テストしました。

このプロセスについては、ステップごとに説明します。

ステップ1-Stockを表すJAVAクラスを作成します

*_ファイル: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-ポートフォリオクラスのテスト

Stockserviceのモックを注入して、Portfolioクラスをテストしましょう。 MockはMockitoによって作成されます。

*_ファイル:PortfolioTester.java_*
package com.finddevguides.mock;

import java.util.ArrayList;
import java.util.List;

import static org.mockito.Mockito.*;

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 = mock(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
      when(stockService.getPrice(googleStock)).thenReturn(50.00);
      when(stockService.getPrice(microsoftStock)).thenReturn(1000.00);

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

ステップ5-結果を確認する

次のように javac コンパイラを使用してクラスをコンパイルします-

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

次に、結果を確認するためにPortfolioTesterを実行します-

C:\Mockito_WORKSPACE>java PortfolioTester

出力を確認する

pass

Mockito-JUnit統合

この章では、JUnitとMockitoを統合する方法を学びます。 ここでは、CalculatorServiceを使用して加算、減算、乗算、除算などの基本的な数学演算を実行する数学アプリケーションを作成します。

Mockitoを使用して、CalculatorServiceのダミー実装をモックします。 さらに、アノテーションを広範囲に使用して、JUnitとMockitoの両方との互換性を紹介しました。

このプロセスについては、ステップごとに説明します。

ステップ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-MathApplicationを表すJAVAクラスを作成します

*_ファイル: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クラスをテストしましょう。 MockはMockitoによって作成されます。

*_ファイル:MathApplicationTester.java_*
import static org.mockito.Mockito.when;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class MathApplicationTester {

  //@InjectMocks annotation is used to create and inject the mock object
   @InjectMocks
   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
      when(calcService.add(10.0,20.0)).thenReturn(30.00);

     //test the add functionality
      Assert.assertEquals(mathApplication.add(10.0, 20.0),30.0,0);
   }
}

ステップ4-テストケースに実行するクラスを作成します

*C> Mockito_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:\Mockito_WORKSPACE>javac CalculatorService.java MathApplication.
   java MathApplicationTester.java TestRunner.java

次に、テストランナーを実行して結果を確認します-

C:\Mockito_WORKSPACE>java TestRunner

出力を確認します。

true

JUnitの詳細については、チュートリアルポイントのJUnitチュートリアルを参照してください。

Mockito-動作の追加

Mockitoは、* when()*メソッドを使用して、モックオブジェクトに機能を追加します。 次のコードスニペットをご覧ください。

//add the behavior of calc service to add two numbers
when(calcService.add(10.0,20.0)).thenReturn(30.00);

ここでは、Mockitoに、 calcServiceadd メソッドに10と20を追加する動作を与え、その結果、30.00の値を返すように指示しました。

この時点で、モックは動作を記録し、動作するモックオブジェクトです。

//add the behavior of calc service to add two numbers
when(calcService.add(10.0,20.0)).thenReturn(30.00);

ステップ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-MathApplicationを表すJAVAクラスを作成します

*_ファイル: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クラスをテストしましょう。 MockはMockitoによって作成されます。

*_ファイル:MathApplicationTester.java_*
import static org.mockito.Mockito.when;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class MathApplicationTester {

  //@InjectMocks annotation is used to create and inject the mock object
   @InjectMocks
   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
      when(calcService.add(10.0,20.0)).thenReturn(30.00);

     //test the add functionality
      Assert.assertEquals(mathApplication.add(10.0, 20.0),30.0,0);
   }
}

ステップ4-テストケースの実行

*C:\> Mockito_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:\Mockito_WORKSPACE>javac CalculatorService.java MathApplication.
   java MathApplicationTester.java TestRunner.java

次に、テストランナーを実行して結果を確認します-

C:\Mockito_WORKSPACE>java TestRunner

出力を確認します。

true

Mockito-動作の検証

Mockitoは、モックメソッドが必要な引数で呼び出されているかどうかを確認できます。 * verify()*メソッドを使用して行われます。 次のコードスニペットをご覧ください。

//test the add functionality
Assert.assertEquals(calcService.add(10.0, 20.0),30.0,0);

//verify call to calcService is made or not with same arguments.
verify(calcService).add(10.0, 20.0);

例-同じ引数を持つ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-MathApplicationを表すJAVAクラスを作成します

*_ファイル: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クラスをテストしましょう。 MockはMockitoによって作成されます。

*_ファイル:MathApplicationTester.java_*
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class MathApplicationTester {

  //@InjectMocks annotation is used to create and inject the mock object
   @InjectMocks
   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
      when(calcService.add(10.0,20.0)).thenReturn(30.00);

     //test the add functionality
      Assert.assertEquals(calcService.add(10.0, 20.0),30.0,0);

     //verify the behavior
      verify(calcService).add(10.0, 20.0);
   }
}

ステップ4-テストケースの実行

*C:\> Mockito_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:\Mockito_WORKSPACE>javac CalculatorService.java MathApplication.
   java MathApplicationTester.java TestRunner.java

テストランナーを実行して結果を確認します

C:\Mockito_WORKSPACE>java TestRunner

出力を確認します。

true

例-異なる引数を持つverify()

ステップ1-数学関数を提供するCalculatorCalcServiceインターフェイスを作成します

*_ファイル: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-MathApplicationを表すJAVAクラスを作成します

*_ファイル: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クラスをテストしましょう。 MockはMockitoによって作成されます。

*_ファイル:MathApplicationTester.java_*
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class MathApplicationTester {

  //@InjectMocks annotation is used to create and inject the mock object
   @InjectMocks
   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
      when(calcService.add(10.0,20.0)).thenReturn(30.00);

     //test the add functionality
      Assert.assertEquals(calcService.add(10.0, 20.0),30.0,0);

     //verify the behavior
      verify(calcService).add(20.0, 30.0);
   }
}

ステップ4-テストケースの実行

*C:\> Mockito_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:\Mockito_WORKSPACE>javac CalculatorService.java MathApplication.
   java MathApplicationTester.java TestRunner.java

次に、テストランナーを実行して結果を確認します-

C:\Mockito_WORKSPACE>java TestRunner

出力を確認します。

testAdd(MathApplicationTester):
Argument(s) are different! Wanted:
calcService.add(20.0, 30.0);
-> at MathApplicationTester.testAdd(MathApplicationTester.java:32)
Actual invocation has different arguments:
calcService.add(10.0, 20.0);
-> at MathApplication.add(MathApplication.java:10)

false

Mockito-コールを期待

Mockitoは、特定のメソッドで実行できる呼び出しの数に特別なチェックを提供します。 MathApplicationがCalculatorService.serviceUsed()メソッドを1回だけ呼び出す必要があり、CalculatorService.serviceUsed()を複数回呼び出すことができないと仮定します。

//add the behavior of calc service to add two numbers
when(calcService.add(10.0,20.0)).thenReturn(30.00);

//limit the method call to 1, no less and no more calls are allowed
verify(calcService, times(1)).add(10.0, 20.0);

次のように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);
}

ステップ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-MathApplicationを表すJAVAクラスを作成します

*_ファイル: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クラスをテストしましょう。 MockはMockitoによって作成されます。

*_ファイル:MathApplicationTester.java_*
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.never;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class MathApplicationTester {

  //@InjectMocks annotation is used to create and inject the mock object
   @InjectMocks
   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
      when(calcService.add(10.0,20.0)).thenReturn(30.00);

     //add the behavior of calc service to subtract two numbers
      when(calcService.subtract(20.0,10.0)).thenReturn(10.00);

     //test the add functionality
      Assert.assertEquals(mathApplication.add(10.0, 20.0),30.0,0);
      Assert.assertEquals(mathApplication.add(10.0, 20.0),30.0,0);
      Assert.assertEquals(mathApplication.add(10.0, 20.0),30.0,0);

     //test the subtract functionality
      Assert.assertEquals(mathApplication.subtract(20.0, 10.0),10.0,0.0);

     //default call count is 1
      verify(calcService).subtract(20.0, 10.0);

     //check if add function is called three times
      verify(calcService, times(3)).add(10.0, 20.0);

     //verify that method was never called on a mock
      verify(calcService, never()).multiply(10.0,20.0);
   }
}

ステップ4-テストケースの実行

*C:\> Mockito_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:\Mockito_WORKSPACE>javac CalculatorService.java MathApplication.
   java MathApplicationTester.java TestRunner.java

次に、テストランナーを実行して結果を確認します-

C:\Mockito_WORKSPACE>java TestRunner

出力を確認します。

true

Mockito-さまざまな呼び出し

Mockitoは、予想されるコールカウントを変えるために、次の追加メソッドを提供します。

  • * atLeast(int min)*-最小の呼び出しを想定しています。
  • * atLeastOnce()*-少なくとも1つの呼び出しが必要です。
  • * atMost(int max)*-最大呼び出しを期待します。

ステップ1-数学関数を提供するCalculatorCalcServiceインターフェイスを作成します

*_ファイル: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-MathApplicationを表すJAVAクラスを作成します

*_ファイル: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クラスをテストしましょう。 MockはMockitoによって作成されます。

*_ファイル:MathApplicationTester.java_*
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atMost;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class MathApplicationTester {

  //@InjectMocks annotation is used to create and inject the mock object
   @InjectMocks
   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
      when(calcService.add(10.0,20.0)).thenReturn(30.00);

     //add the behavior of calc service to subtract two numbers
      when(calcService.subtract(20.0,10.0)).thenReturn(10.00);

     //test the add functionality
      Assert.assertEquals(mathApplication.add(10.0, 20.0),30.0,0);
      Assert.assertEquals(mathApplication.add(10.0, 20.0),30.0,0);
      Assert.assertEquals(mathApplication.add(10.0, 20.0),30.0,0);

     //test the subtract functionality
      Assert.assertEquals(mathApplication.subtract(20.0, 10.0),10.0,0.0);

     //check a minimum 1 call count
      verify(calcService, atLeastOnce()).subtract(20.0, 10.0);

     //check if add function is called minimum 2 times
      verify(calcService, atLeast(2)).add(10.0, 20.0);

     //check if add function is called maximum 3 times
      verify(calcService, atMost(3)).add(10.0,20.0);
   }
}

ステップ4-テストケースの実行

*C:\> Mockito_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:\Mockito_WORKSPACE>javac CalculatorService.java MathApplication.
   java MathApplicationTester.java TestRunner.java

次に、テストランナーを実行して結果を確認します-

C:\Mockito_WORKSPACE>java TestRunner

出力を確認します。

true

Mockito-例外処理

Mockitoは、モックに例外をスローする機能を提供するため、例外処理をテストできます。 次のコードスニペットをご覧ください。

//add the behavior to throw exception
doThrow(new Runtime Exception("divide operation not implemented"))
   .when(calcService).add(10.0,20.0);

ここでは、モックオブジェクトに例外節を追加しました。 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-MathApplicationを表すJAVAクラスを作成します

*_ファイル: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クラスをテストしましょう。 MockはMockitoによって作成されます。

*_ファイル:MathApplicationTester.java_*
import static org.mockito.Mockito.doThrow;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoRunner.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
      doThrow(new RuntimeException("Add operation not implemented"))
         .when(calcService).add(10.0,20.0);

     //test the add functionality
      Assert.assertEquals(mathApplication.add(10.0, 20.0),30.0,0);
   }
}

ステップ4-テストケースの実行

*C:\> Mockito_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:\Mockito_WORKSPACE>javac CalculatorService.java MathApplication.
   java MathApplicationTester.java TestRunner.java

次に、テストランナーを実行して結果を確認します-

C:\Mockito_WORKSPACE>java TestRunner

出力を確認します。

testAdd(MathApplicationTester): Add operation not implemented
false

Mockito-モックの作成

これまで、アノテーションを使用してモックを作成してきました。 Mockitoは、モックオブジェクトを作成するためのさまざまなメソッドを提供します。 mock()は、モックがそのアクションの途中で行うメソッド呼び出しの順序を気にせずにモックを作成します。

構文

calcService = mock(CalculatorService.class);

ステップ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-MathApplicationを表すJAVAクラスを作成します

*_ファイル: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クラスをテストしましょう。 MockはMockitoによって作成されます。

ここでは、2つのモックメソッド呼び出しadd()とminus()をwhen()を介してモックオブジェクトに追加しました。 ただし、テスト中は、add()を呼び出す前に、subtract()を呼び出しました。 create()を使用してモックオブジェクトを作成する場合、メソッドの実行順序は重要ではありません。

*_ファイル:MathApplicationTester.java_*
package com.finddevguides.mock;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;

//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class MathApplicationTester {

   private MathApplication mathApplication;
   private CalculatorService calcService;

   @Before
   public void setUp(){
      mathApplication = new MathApplication();
      calcService = mock(CalculatorService.class);
      mathApplication.setCalculatorService(calcService);
   }

   @Test
   public void testAddAndSubtract(){

     //add the behavior to add numbers
      when(calcService.add(20.0,10.0)).thenReturn(30.0);

     //subtract the behavior to subtract numbers
      when(calcService.subtract(20.0,10.0)).thenReturn(10.0);

     //test the subtract 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
      verify(calcService).add(20.0,10.0);
      verify(calcService).subtract(20.0,10.0);
   }
}

ステップ4-テストケースの実行

*C:\> Mockito_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:\Mockito_WORKSPACE>javac CalculatorService.java MathApplication.
   java MathApplicationTester.java TestRunner.java

次に、テストランナーを実行して結果を確認します-

C:\Mockito_WORKSPACE>java TestRunner

出力を確認します。

true

Mockito-順序付けられた検証

Mockitoは、モックがそのアクションの途中で行うメソッド呼び出しの順序を処理するInorderクラスを提供します。

構文

//create an inOrder verifier for a single mock
InOrder inOrder = inOrder(calcService);

//following will make sure that add is first called then subtract is called.
inOrder.verify(calcService).add(20.0,10.0);
inOrder.verify(calcService).subtract(20.0,10.0);

ステップ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-MathApplicationを表すJAVAクラスを作成します

*_ファイル: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クラスをテストしましょう。 MockはMockitoによって作成されます。

ここでは、2つのモックメソッド呼び出しadd()とminus()をwhen()を介してモックオブジェクトに追加しました。 ただし、テスト中は、add()を呼び出す前に、subtract()を呼び出しました。 Mockitoを使用してモックオブジェクトを作成する場合、メソッドの実行順序は重要ではありません。 InOrderクラスを使用して、呼び出し順序を確認できます。

*_ファイル:MathApplicationTester.java_*
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.inOrder;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.runners.MockitoJUnitRunner;

//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class MathApplicationTester {

   private MathApplication mathApplication;
   private CalculatorService calcService;

   @Before
   public void setUp(){
      mathApplication = new MathApplication();
      calcService = mock(CalculatorService.class);
      mathApplication.setCalculatorService(calcService);
   }

   @Test
   public void testAddAndSubtract(){

     //add the behavior to add numbers
      when(calcService.add(20.0,10.0)).thenReturn(30.0);

     //subtract the behavior to subtract numbers
      when(calcService.subtract(20.0,10.0)).thenReturn(10.0);

     //test the add functionality
      Assert.assertEquals(mathApplication.add(20.0, 10.0),30.0,0);

     //test the subtract functionality
      Assert.assertEquals(mathApplication.subtract(20.0, 10.0),10.0,0);

     //create an inOrder verifier for a single mock
      InOrder inOrder = inOrder(calcService);

     //following will make sure that add is first called then subtract is called.
      inOrder.verify(calcService).subtract(20.0,10.0);
      inOrder.verify(calcService).add(20.0,10.0);

   }
}

ステップ4-テストケースの実行

*C:\> Mockito_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:\Mockito_WORKSPACE>javac CalculatorService.java MathApplication.
   java MathApplicationTester.java TestRunner.java

次に、テストランナーを実行して結果を確認します-

C:\Mockito_WORKSPACE>java TestRunner

出力を確認します。

testAddAndSubtract(MathApplicationTester):
Verification in order failure
Wanted but not invoked:
calculatorService.add(20.0, 10.0);
-> at MathApplicationTester.testAddAndSubtract(MathApplicationTester.java:48)
Wanted anywhere AFTER following interaction:
calculatorService.subtract(20.0, 10.0);
-> at MathApplication.subtract(MathApplication.java:13)
false

Mockito-コールバック

Mockitoは、汎用インターフェイスでのスタブを可能にするAnswerインターフェイスを提供します。

構文

//add the behavior to add numbers
when(calcService.add(20.0,10.0)).thenAnswer(new Answer<Double>() {
   @Override
   public Double answer(InvocationOnMock invocation) throws Throwable {
     //get the arguments passed to mock
      Object[] args = invocation.getArguments();
     //get the mock
      Object mock = invocation.getMock();
     //return the result
      return 30.0;
   }
});

ステップ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-MathApplicationを表すJAVAクラスを作成します

*_ファイル: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クラスをテストしましょう。 MockはMockitoによって作成されます。

ここでは、1つのモックメソッド呼び出し、when()を介してモックオブジェクトにadd()を追加しました。 ただし、テスト中は、add()を呼び出す前に、subtract()を呼び出しました。 Mockito.createStrictMock()を使用してモックオブジェクトを作成する場合、メソッドの実行順序は重要です。

*_ファイル:MathApplicationTester.java_*
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.inOrder;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.runners.MockitoJUnitRunner;

//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class MathApplicationTester {

   private MathApplication mathApplication;
   private CalculatorService calcService;

   @Before
   public void setUp(){
      mathApplication = new MathApplication();
      calcService = mock(CalculatorService.class);
      mathApplication.setCalculatorService(calcService);
   }

   @Test
   public void testAdd(){

     //add the behavior to add numbers
      when(calcService.add(20.0,10.0)).thenAnswer(new Answer<Double>() {

         @Override
         public Double answer(InvocationOnMock invocation) throws Throwable {
           //get the arguments passed to mock
            Object[] args = invocation.getArguments();

           //get the mock
            Object mock = invocation.getMock();

           //return the result
            return 30.0;
         }
      });

     //test the add functionality
      Assert.assertEquals(mathApplication.add(20.0, 10.0),30.0,0);
   }
}

ステップ4-テストケースの実行

*C:\> Mockito_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:\Mockito_WORKSPACE>javac CalculatorService.java MathApplication.
   java MathApplicationTester.java TestRunner.java

次に、テストランナーを実行して結果を確認します-

C:\Mockito_WORKSPACE>java TestRunner

出力を確認します。

true

モッキート-スパイ

Mockitoは、実際のオブジェクトにスパイを作成するオプションを提供します。 spyが呼び出されると、実際のオブジェクトの実際のメソッドが呼び出されます。

構文

//create a spy on actual object
calcService = spy(calculator);

//perform operation on real object
//test the add functionality
Assert.assertEquals(mathApplication.add(20.0, 10.0),30.0,0);

ステップ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-MathApplicationを表すJAVAクラスを作成します

*_ファイル: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クラスをテストしましょう。 MockはMockitoによって作成されます。

ここでは、1つのモックメソッド呼び出し、when()を介してモックオブジェクトにadd()を追加しました。 ただし、テスト中は、add()を呼び出す前に、subtract()を呼び出しました。 Mockito.createStrictMock()を使用してモックオブジェクトを作成する場合、メソッドの実行順序は重要です。

*_ファイル:MathApplicationTester.java_*
import static org.mockito.Mockito.spy;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;

//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class MathApplicationTester {

   private MathApplication mathApplication;
   private CalculatorService calcService;

   @Before
   public void setUp(){
      mathApplication = new MathApplication();
      Calculator calculator = new Calculator();
      calcService = spy(calculator);
      mathApplication.setCalculatorService(calcService);
   }

   @Test
   public void testAdd(){

     //perform operation on real object
     //test the add functionality
      Assert.assertEquals(mathApplication.add(20.0, 10.0),30.0,0);
   }

   class Calculator implements CalculatorService {
      @Override
      public double add(double input1, double input2) {
         return input1 + input2;
      }

      @Override
      public double subtract(double input1, double input2) {
         throw new UnsupportedOperationException("Method not implemented yet!");
      }

      @Override
      public double multiply(double input1, double input2) {
         throw new UnsupportedOperationException("Method not implemented yet!");
      }

      @Override
      public double divide(double input1, double input2) {
         throw new UnsupportedOperationException("Method not implemented yet!");
      }
   }
}

ステップ4-テストケースの実行

*C:\> Mockito_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:\Mockito_WORKSPACE>javac CalculatorService.java MathApplication.
   java MathApplicationTester.java TestRunner.java

次に、テストランナーを実行して結果を確認します-

C:\Mockito_WORKSPACE>java TestRunner

出力を確認します。

true

Mockito-モックのリセット

Mockitoは、後で再利用できるように、モックをリセットする機能を提供します。 次のコードスニペットをご覧ください。

//reset mock
reset(calcService);

ここで、モックオブジェクトをリセットしました。 MathApplicationはcalcServiceを使用し、モックをリセットした後、モックメソッドを使用するとテストが失敗します。

ステップ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-MathApplicationを表すJAVAクラスを作成します

*_ファイル: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クラスをテストしましょう。 MockはMockitoによって作成されます。

*_ファイル:MathApplicationTester.java_*
package com.finddevguides.mock;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.reset;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;

//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class MathApplicationTester {

   private MathApplication mathApplication;
   private CalculatorService calcService;

   @Before
   public void setUp(){
      mathApplication = new MathApplication();
      calcService = mock(CalculatorService.class);
      mathApplication.setCalculatorService(calcService);
   }

   @Test
   public void testAddAndSubtract(){

     //add the behavior to add numbers
      when(calcService.add(20.0,10.0)).thenReturn(30.0);

     //test the add functionality
      Assert.assertEquals(mathApplication.add(20.0, 10.0),30.0,0);

     //reset the mock
      reset(calcService);

     //test the add functionality after resetting the mock
      Assert.assertEquals(mathApplication.add(20.0, 10.0),30.0,0);
   }
}

ステップ4-テストケースの実行

*C:\> Mockito_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:\Mockito_WORKSPACE>javac CalculatorService.java MathApplication.
   java MathApplicationTester.java TestRunner.java

次に、テストランナーを実行して結果を確認します-

C:\Mockito_WORKSPACE>java TestRunner

出力を確認します。

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

Mockito-行動駆動開発

Behavior Driven Developmentは、テストメソッドとして givenwhen および then 形式を使用するテストを記述するスタイルです。 Mockitoは、そうするための特別な方法を提供します。 次のコードスニペットをご覧ください。

//Given
given(calcService.add(20.0,10.0)).willReturn(30.0);

//when
double result = calcService.add(20.0,10.0);

//then
Assert.assertEquals(result,30.0,0);

ここでは、 when メソッドの代わりにBDDMockitoクラスの given メソッドを使用しています。

ステップ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-MathApplicationを表すJAVAクラスを作成します

*_ファイル: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クラスをテストしましょう。 MockはMockitoによって作成されます。

*_ファイル:MathApplicationTester.java_*
package com.finddevguides.mock;

import static org.mockito.BDDMockito.*;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;

//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class MathApplicationTester {

   private MathApplication mathApplication;
   private CalculatorService calcService;

   @Before
   public void setUp(){
      mathApplication = new MathApplication();
      calcService = mock(CalculatorService.class);
      mathApplication.setCalculatorService(calcService);
   }

   @Test
   public void testAdd(){

     //Given
      given(calcService.add(20.0,10.0)).willReturn(30.0);

     //when
      double result = calcService.add(20.0,10.0);

     //then
      Assert.assertEquals(result,30.0,0);
   }
}

ステップ4-テストケースの実行

*C:\> Mockito_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:\Mockito_WORKSPACE>javac CalculatorService.java MathApplication.
   java MathApplicationTester.java TestRunner.java

次に、テストランナーを実行して結果を確認します-

C:\Mockito_WORKSPACE>java TestRunner

出力を確認します。

true

Mockito-タイムアウト

Mockitoには、規定の時間枠内でメソッドが呼び出されるかどうかをテストする特別なタイムアウトオプションがあります。

構文

//passes when add() is called within 100 ms.
verify(calcService,timeout(100)).add(20.0,10.0);

ステップ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-MathApplicationを表すJAVAクラスを作成します

*_ファイル: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クラスをテストしましょう。 MockはMockitoによって作成されます。

*_ファイル:MathApplicationTester.java_*
package com.finddevguides.mock;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;

//@RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class MathApplicationTester {

   private MathApplication mathApplication;
   private CalculatorService calcService;

   @Before
   public void setUp(){
      mathApplication = new MathApplication();
      calcService = mock(CalculatorService.class);
      mathApplication.setCalculatorService(calcService);
   }

   @Test
   public void testAddAndSubtract(){

     //add the behavior to add numbers
      when(calcService.add(20.0,10.0)).thenReturn(30.0);

     //subtract the behavior to subtract numbers
      when(calcService.subtract(20.0,10.0)).thenReturn(10.0);

     //test the subtract 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 add method to be completed within 100 ms
      verify(calcService, timeout(100)).add(20.0,10.0);

     //invocation count can be added to ensure multiplication invocations
     //can be checked within given timeframe
      verify(calcService, timeout(100).times(1)).subtract(20.0,10.0);
   }
}

ステップ4-テストケースの実行

*C:\> Mockito_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:\Mockito_WORKSPACE>javac CalculatorService.java MathApplication.
   java MathApplicationTester.java TestRunner.java

次に、テストランナーを実行して結果を確認します-

C:\Mockito_WORKSPACE>java TestRunner

出力を確認します。

true