Mockito是一個Java平台開源測試框架英語List of unit testing frameworks,在MIT許可證下發佈。[3][4]該框架允許在自動化單元測試中創建測試替身英語Test double對象(模擬對象),用於測試驅動開發(TDD)或行為驅動開發(BDD)。

Mockito
開發者斯蒂芬·費伯(Szczepan Faber)、布萊斯·杜泰爾(Brice Dutheil)、拉斐爾·溫特哈特(Rafael Winterhalter)、蒂姆·范德利普(Tim van der Lippe)等
當前版本2022年4月21日,​2年前​(2022-04-21[1]
原始碼庫github.com/mockito/mockito
程式語言Java
類型測試
許可協議MIT許可證[2]
網站site.mockito.org

該框架的名稱和圖標是對莫吉托(Mojito,一種飲料)的模仿。

特點

Mockito允許開發人員驗證被測系統(SUT)的行為,而無需事先建立期望。[5]對於模擬對象,有人批評其測試代碼與被測系統的緊耦合。[6]Mockito試圖通過取消期望規範,來擺脫「期望-運行-驗證」的模式。[7]Mockito還提供了一些用於減少樣板代碼英語Boilerplate code的註解。[8]

起源

Mockito是從擴展EasyMock英語EasyMock的語法和功能開始的。[9][10]

例子

下面是一個非耦合Hello world程序;我們可以對它的某些部分進行單元測試,對其它部分使用模擬對象

package org.examples;

import java.io.IOException;

public class HelloApplication {

   public static interface Greeter {
      String getGreeting(String subject);
      String getIntroduction(String actor);
   }
   
   public static class HelloGreeter implements Greeter {
      private String hello;
      private String segmenter;
      
      public HelloGreeter(String hello, String segmenter) {
         this.hello = hello;
         this.segmenter = segmenter;
      }
      public String getGreeting(String subject) {
         return hello + " " + subject; 
      }
      public String getIntroduction(String actor) {
         return actor+segmenter;
      }
   }
   
   public static interface HelloActable {
      void sayHello(String actor, String subject) throws IOException;
   }
   
   public static class HelloAction implements HelloActable {
      private Greeter helloGreeter;
      private Appendable helloWriter;

      public HelloAction(Greeter helloGreeter, Appendable helloWriter) {
         super();
         this.helloGreeter = helloGreeter;
         this.helloWriter = helloWriter;
      }
      public void sayHello(String actor, String subject) throws IOException { 
         helloWriter.append(helloGreeter.getIntroduction(actor)).append(helloGreeter.getGreeting(subject));
      }
   }

   public static void main(String... args) throws IOException {
      new HelloAction(new HelloGreeter("hello", ": "), System.out).sayHello("application", "world");
   }

}

啟動HelloApplication後,結果如下:

application: hello world

HelloActable組件的單元測試可能如下:

package org.examples;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.Before;
import org.junit.Test;

import org.examples.HelloApplication.HelloActable;
import org.examples.HelloApplication.HelloAction;
import org.examples.HelloApplication.Greeter;

public class HelloActionUnitTest {
   
   Greeter helloGreeterMock;
   Appendable helloWriterMock;
   HelloActable helloAction;
   
   @Before
   public void setUp() {
      helloGreeterMock = mock(Greeter.class);
      helloWriterMock = mock(Appendable.class);
      helloAction = new HelloAction(helloGreeterMock, helloWriterMock);
   }
   
   @Test
   public void testSayHello() throws Exception {
      when(helloWriterMock.append(any(String.class))).thenReturn(helloWriterMock);
      when(helloGreeterMock.getIntroduction(eq("unitTest"))).thenReturn("unitTest : ");
      when(helloGreeterMock.getGreeting(eq("world"))).thenReturn("hi world");
      
      helloAction.sayHello("unitTest", "world");
      
      verify(helloGreeterMock).getIntroduction(eq("unitTest"));
      verify(helloGreeterMock).getGreeting(eq("world"));

      verify(helloWriterMock, times(2)).append(any(String.class));
      verify(helloWriterMock, times(1)).append(eq("unitTest : "));
      verify(helloWriterMock, times(1)).append(eq("hi world"));
   }
}

它為Greeter和Appendable接口使用了模擬對象,並隱式假設了下一個用例:

unitTest : hi world

用於測試Greeter與HelloActable聯合在一起的集成測試代碼可能如下:

package org.examples;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.Before;
import org.junit.Test;

import org.examples.HelloApplication.HelloActable;
import org.examples.HelloApplication.HelloAction;
import org.examples.HelloApplication.Greeter;
import org.examples.HelloApplication.HelloGreeter;

public class HelloActionIntegrationTest {
   HelloActable helloAction;
   Greeter helloGreeter;
   Appendable helloWriterMock;
   
   @Before
   public void setUp() {
      helloGreeter = new HelloGreeter("welcome", " says ");
      helloWriterMock = mock(Appendable.class);
      helloAction = new HelloAction(helloGreeter, helloWriterMock);
   }
   
   @Test
   public void testSayHello() throws Exception {
      when(helloWriterMock.append(any(String.class))).thenReturn(helloWriterMock);

      helloAction.sayHello("integrationTest", "universe");

      verify(helloWriterMock, times(2)).append(any(String.class));
      verify(helloWriterMock, times(1)).append(eq("integrationTest says "));
      verify(helloWriterMock, times(1)).append(eq("welcome universe"));
   }
}

它僅使用模擬對象代替Appendable接口,而使用其它(HelloActable和Greeter)接口的真實實現,並隱式假設了下一個用例:

integrationTest says welcome universe

從HelloActionUnitTest和HelloActionIntegrationTest這兩個類的import語句可以看出,需要在類路徑英語Classpath中加入一些Mockito和JUnit才能編譯和運行測試類。

參見

參考資料

  1. ^ Project Releases Overview on GitHub [GitHub上的項目發佈概覽]. GitHub. [2022-04-29]. (原始內容存檔於2023-08-28) (英語). 
  2. ^ License · mockito/mockito Wiki [許可證·mockito/mockito Wiki]. GitHub. [2019-08-30]. (原始內容存檔於2023-06-14) (英語). 
  3. ^ Mockito in six easy examples [Mockito六個簡單的例子]. 2009 [2012-10-05]. (原始內容存檔於2023-06-14) (英語). 
  4. ^ What's the best mock framework for Java? [Java最好的模擬框架是什麼?]. [2010-12-29]. (原始內容存檔於2023-11-02) (英語). 
  5. ^ Features and Motivations [特點與動機]. [2010-12-29]. (原始內容存檔於2016-03-22) (英語). 
  6. ^ Fowler, Martin. Mocks Aren't Stubs [模擬不是空殼]. 2007 [2010-12-29]. (原始內容存檔於2008-03-19) (英語). 
  7. ^ Faber, Szczepan. Death Wish [期望之死]. [2010-12-29]. (原始內容存檔於2009-11-30) (英語). 
  8. ^ Kaczanowski, Tomek. Mockito - Open Source Java Mocking Framework [Mockito——開源的Java模擬框架]. [2013-09-17]. (原始內容存檔於2023-06-15) (英語). 
  9. ^ Faber, Szczepan. Mockito. [2010-12-29]. (原始內容存檔於2010-03-29) (英語). 
  10. ^ Mockito Home Page [Mockito主頁]. [2010-12-29]. (原始內容存檔於2017-04-21) (英語). 

外部連結