Mockito

Mockito是一个Java平台的开源测试框架（英语：List of unit testing frameworks），在MIT许可证下发布。该框架允许在自动化单元测试中创建测试替身（英语：Test double）对象（模拟对象），用于测试驱动开发（TDD）或行为驱动开发（BDD）。 该框架的名称和图标是对莫吉托（Mojito，一种饮料）的模仿。 Mockito允许开发人员验证被测系统（SUT）的行为，而无需事先建立期望。对于模拟对象，有人批评其测试代码与被测系统的紧耦合。Mockito试图通过取消期望规范，来摆脱“期望-运行-验证”的模式。Mockito还提供了一些用于减少样板代码（英语：Boilerplate code）的注解。 Mockito是从扩展EasyMock（英语：EasyMock）的语法和功能开始的。 下面是一个非耦合的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的包才能编译和运行测试类。 行为驱动开发 单元测试框架列表（英语：List of unit testing frameworks） 软件测试 Project Releases Overview on GitHub [GitHub上的项目发布概览]. GitHub. [2022-04-29]. （原始内容存档于2023-08-28） （英语）.  License · mockito/mockito Wiki [许可证·mockito/mockito Wiki]. GitHub. [2019-08-30]. （原始内容存档于2023-06-14） （英语）.  Mockito in six easy examples [Mockito六个简单的例子]. 2009 [2012-10-05]. （原始内容存档于2023-06-14） （英语）.  What's the best mock framework for Java? [Java最好的模拟框架是什么？]. [2010-12-29]. （原始内容存档于2023-11-02） （英语）.  Features and Motivations [特点与动机]. [2010-12-29]. （原始内容存档于2016-03-22） （英语）.  Fowler, Martin. Mocks Aren't Stubs [模拟不是空壳]. 2007 [2010-12-29]. （原始内容存档于2008-03-19） （英语）.  Faber, Szczepan. Death Wish [期望之死]. [2010-12-29]. （原始内容存档于2009-11-30） （英语）.  Kaczanowski, Tomek. Mockito - Open Source Java Mocking Framework [Mockito——开源的Java模拟框架]. [2013-09-17]. （原始内容存档于2023-06-15） （英语）.  Faber, Szczepan. Mockito. [2010-12-29]. （原始内容存档于2010-03-29） （英语）.  Mockito Home Page [Mockito主页]. [2010-12-29]. （原始内容存档于2017-04-21） （英语）.  官方网站