概述
一:创建mock/spy对象
0:概述
Mockito可以帮助我们方便的创建被测对象、mock对象和spy对象。
- 创建被测对象:
- 先解释一下被测对象:就是单元测试中我们想要测试的那个类。如xxxService、xxxUtils等等。
- 使用@InjectMocks注解创建:
- 配合
@RunWith(MockitoJUnitRunner.class)
使用或在@Before
方法中使用MockitoAnnotations.openMocks(this)
来激活Mockito 注解的相关功能。 - 如果同时也使用了@Mock注解或者@Spy注解。Mockito可以方便的将这两个注解生成的对象注入到@InjectMocks注解的对象的成员变量中。
- 配合
- 直接创建:
- 当然我们可以直接new一个被测对象,但是我们不能方便的使用Mockito为我们提供的自动注入成员变量的功能了。当然我们可以手动的现在这些注入的工作。
- 创建mock对象:
- mock对象:一般是被测对象依赖的对象(比如被测对象的成员变量)。
- 使用@Mock注解:
- 配合
@RunWith(MockitoJUnitRunner.class)
使用或在@Before
方法中使用MockitoAnnotations.openMocks(this)
来激活Mockito 注解的相关功能。 - 被@Mock注解的对象会被自动注入到@InjectMocks注解生成的被测对象中。
- 配合
- 使用Mockito.mock();
- 生成的mock对象需要手动配置到被测对象中,不推荐。
- 注意:
- mock对象中的方法被调用时默认会返回对应类型对象的空值。方法实际的代码不会被执行。当前如果我们想要执行实际的代码也是可以的:
- 我么可以先对此方法进行存根操作,此时使用doCallRealMethod()或者thenCallRealMethod()方法即可。下文会具体描述如何操作。
- 也可以通过指定返回值策略(Mockito.CALLS_REAL_METHODS)的方式实现。即创建mock对象时指定返回值策略为Mockito.CALLS_REAL_METHODS。
- mock对象中的方法被调用时默认会返回对应类型对象的空值。许多情况下当我们不对某个方进行存根时那么返回的值就是null,测试过程中就会产生NPE。但是我们可以在创建mock对象时指定返回值生成策略(Answer策略)。下文会具体描述如何操作。
- mock对象中的方法被调用时默认会返回对应类型对象的空值。方法实际的代码不会被执行。当前如果我们想要执行实际的代码也是可以的:
- 创建spy对象:
- spy对象:部分mock的对象。一般是被测对象依赖的对象(比如被测对象的成员变量)。
- 使用@Spy注解:
- 配合
@RunWith(MockitoJUnitRunner.class)
使用或在@Before
方法中使用MockitoAnnotations.openMocks(this)
来激活Mockito 注解的相关功能。 - 被@Spy注解的对象会被自动注入到@InjectMocks注解生成的被测对象中。
- 配合
- 使用Mockito.spy();
- 生成的spy对象需要手动配置到被测对象中,不推荐。
- 注意:
- spy对象中的方法被调用时默认情况下方法实际的代码会被执行。当前如果我们想要不执行实际的代码也是可以的:
- 我么可以先对此方法进行存根操作,此时使用doXXXX()方法即可(注意不要使用或者thenXXXX()方法,会给我们带来麻烦:实际的代码会在此时被调用一次)。下文会具体描述如何操作。
- spy对象中的方法被调用时默认情况下方法实际的代码会被执行。当前如果我们想要不执行实际的代码也是可以的:
1:创建mock对象
-
使用Mockito.mock()方法。
//org.mockito.Mockito.mock(java.lang.Class<T>) //org.mockito.Mockito.mock(java.lang.Class<T>, java.lang.String) //org.mockito.Mockito.mock(java.lang.Class<T>, org.mockito.stubbing.Answer) //org.mockito.Mockito.mock(java.lang.Class<T>, org.mockito.MockSettings) //方式1 Foo foo1 = Mockito.mock(Foo.class); //方式2:给mock指定名称 Foo foo2 = Mockito.mock(Foo.class, "mock_1"); //方式3:给mock指定自定义返回逻辑 Foo foo3 = Mockito.mock(Foo.class, new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { //自定义返回逻辑 return null; } }); //方式4:使用MockSettings配置当前mock Foo foo4 = Mockito.mock(Foo.class, Mockito.withSettings().defaultAnswer(Mockito.RETURNS_SMART_NULLS)); 复制代码
-
使用@InjectMocks和@Mock注解。
- 被@InjectMocks注解的对象就是要被我们测试的对象,它会被自动的实例化。且其包含的成员变量会被相应的@Mock注解的对象自动赋值。注意观察下面的示例:
- 注意使用了
@RunWith(MockitoJUnitRunner.class)
注解。
public class Foo { private Bar bar; public int sum(int a, int b) { return bar.add(a, b); } } 复制代码
public class Bar { public int add(int a, int b) { return a + b; } } 复制代码
//注意我们使用了MockitoJUnitRunner @RunWith(MockitoJUnitRunner.class) public class MockitoTest { //foo 对象内部的成员变量会自动被 @Mock 注解的生成的对象注入。 @InjectMocks private Foo foo; //bar 对象会自动的注入到 @InjectMocks 注解的对象的成员变量中去。 @Mock private Bar bar; @Test public void mockTest() { //先对mock对象的待测方法进行存根,当真正执行到mock对象的此方法时 //会直接返回存根的结果而不会调用mock对象的实际代码 Mockito.when(bar.add(1, 2)).thenReturn(7); int result = foo.sum(1, 2); //验证是否是存根返回的值 Assert.assertEquals(7, result); } } 复制代码
-
注意事项:
-
默认情况下,对于所有方法的返回值,mock 视情况而定将返回 null、原始/原始包装值或空集合。例如 int/Integer 返回0,布尔值/布尔值返回false。我们可以在创建mock时通过指定默认的Answer策略来更改此返回。支持的Answer策略:
- Mockito.RETURNS_DEFAULTS;
- 这个实现首先尝试全局配置,如果没有全局配置,那么它将使用一个返回0、空集合、空值等的默认Answer。
- Mockito.RETURNS_DEEP_STUBS;
- 链式调用避免空指针。
- Mockito.RETURNS_MOCKS;
- 首先尝试返回普通值(0、空集合、空字符串等),然后尝试返回mock。如果返回类型不能被mock(例如final),则返回普通的null。
- Mockito.RETURNS_SELF;
- 允许Builder 的mock在调用方法时返回其本身,该方法返回的Type等于类或父类。 请记住,这个Answer使用方法的返回类型。如果此类型可分配给mock类,则它将返回mock。因此,如果您有一个返回超类(例如Object)的方法,它将匹配并返回mock。
- Mockito.RETURNS_SMART_NULLS;
- 此实现在处理遗留代码时很有帮助。非存根方法通常返回null。如果代码使用非存根调用返回的对象,则会得到NullPointerException。这个Answer的实现返回SmartNull而不是null。SmartNull给出了比NPE更好的异常消息,因为它指出了调用无存根方法的那一行。您只需单击堆栈即可跟踪。 SmartNull首先尝试返回普通值(0,空集合,空字符串等),然后尝试返回SmartNull。如果返回类型是final,则返回纯null。 在Mockito 4.0.0中,ReturnsSmartNulls可能是默认的返回值策略。
- Mockito.CALLS_REAL_METHODS
- 一个调用实际方法(用于部分mock)的Answer。
- Mockito.RETURNS_DEFAULTS;
-
2:创建spy对象
-
使用Mockito.spy()方法
{ //org.mockito.Mockito.spy(java.lang.Class<T>) //org.mockito.Mockito.spy(T) //方式1:spy一个具体的类型 List spy1 = Mockito.spy(List.class); //方式2:spy一个已存在的对象 List spy2 = Mockito.spy(new ArrayList<>()); //便利的 API, 新的重载的 spy() 方法: SomeAbstract spy = spy(SomeAbstract.class); //Mocking 抽象, spy 接口的默认方法(从2.7.13可用) Function function = spy(Function.class); //健壮的 API, 来自 settings builder: OtherAbstract spy = mock(OtherAbstract.class, withSettings() .useConstructor().defaultAnswer(CALLS_REAL_METHODS)); //Mock一个抽象类,使用构造函数(从 2.7.14 可用) SomeAbstract spy = mock(SomeAbstract.class, withSettings() .useConstructor("arg1", 123).defaultAnswer(CALLS_REAL_METHODS)); //mock一个非静态内部抽象类 InnerAbstract spy = mock(InnerAbstract.class,withSettings().useConstructor().outerInstance(outerInstance).defaultAnswer(CALLS_REAL_METHODS)); } 复制代码
-
使用@Spy注解。
- 被@InjectMocks注解的对象一般就是我们被测的对象。它会被自动的实例化。且其包含的成员变量会被相应的@Spy注解的对象自动赋值。注意观察下面的示例:
- 注意使用了
@RunWith(MockitoJUnitRunner.class)
注解。
//注意我们使用了MockitoJUnitRunner @RunWith(MockitoJUnitRunner.class) public class MockitoTest { @InjectMocks private Foo foo; @Spy private Bar bar; //也可以这样 @Spy private Bar bar2 = new Bar(); @Test public void mockTest() { //对spy对象的add方法进行存根 Mockito.when(bar.add(1, 2)).thenReturn(7); int result = foo.sum(1, 2); Assert.assertEquals(7, result); } @Test public void mockTest2() { //不对spy对象存根,则调用实际的方法。 //注意同mock对象的区别:mock对象默认是返回类型的空值。而spy对象是默认执行实际方法并返回。 int result = foo.sum(1, 2); Assert.assertEquals(3, result); } } 复制代码
-
注意事项:
-
与mock对象的区别:
- mock对象的默认返回类型的空值(可以配置返回策略),不执行实际方法。
- spy对象是默认执行实际方法并返回,可以对spy对象的某个方法进行存根以指定返回值且避免调用此方法实际逻辑。
-
有时将
when(Object)
用于已经存根的spy对象是不可能或不切实际的。因此在使用spy时请考虑使用doReturn
|Answer
|Throw()
存根方法族。例子:List list = new LinkedList(); List spy = spy(list); //以下代码是不可能: spy.get(0)方法实际的代码会被调用, 会抛出 //IndexOutOfBoundsException (list仍然是空的)。 //为什么在存根的时候就会调用方法实际的代码?这样不就无法对此方法进行存根了吗? //因为在执行when(spy.get(0))的时候首先执行的是when()方法内的spy.get(0); //而此时spy.get(0)还没有进行存根。故此方法的实际代码会被调用。要解决这个问题, //请使用doXXX()方法配合when()进行存根。 when(spy.get(0)).thenReturn("foo"); //你需要用 doReturn() 去存根 doReturn("foo").when(spy).get(0); 复制代码
-
Mockito 不会将调用传递给的真实实例,实际上创建了它的副本。因此,如果您保留真实实例并与之交互,则不要指望监视的人会知道这些交互及其对真实实例状态的影响。相应的,当unstubbed(没有进行存根)的方法在spy对象上调用但不在真实实例上时,您将看不到对真实实例的任何影响。
- 意思就是spy对象其实是真实对象的一个复制体;对spy中的方法的调用不会影响到真实对象。
-
注意
final方法
。Mockito 不会 mockfinal方法
,所以底线是:当您监视真实对象时(使用spy()方法) + 尝试存根final方法
= 麻烦。您也将无法验证这些方法。
-
3:创建被测对象
-
使用@InjectMocks注解。(需要配合
@RunWith(MockitoJUnitRunner.class)
使用或在@Before
方法中使用MockitoAnnotations.openMocks(this)
来激活Mockito 注解的相关功能。){ @InjectMocks private Foo foo; @Mock private Bar bar; } 复制代码
- 说明:被测对象
foo
内如果包含Bar
类型的成员变量,此时Mockito会自动将bar
注入到foo
中被@InjectMocks
注解的对象foo
在调用其方法时会执行其实际的代码逻辑。而被@Mock
注解的对象bar
中的方法被调用时不会执行实际的代码逻辑,而是返回类型相关的空值。
{ @InjectMocks private Foo foo; @Spy private Bar bar = new Bar(); } 复制代码
- 说明:与上面不同的是
bar
对象是一个spy
对象。默认情况下当bar
对象的某个方法被调用时会执行实际的代码。当然可以对bar
对象的某个方法进行存根,从而指定此方法的返回值,而不用调用其实际方法。要注意的是存根的方式要使用doXXXX(x).when(spy).m1()
而不是when(spy.m1()).thenReturn(x)
的方式;因为后者会在存根过程中会调用一次方法实际的代码逻辑。
- 说明:被测对象
-
注意事项:
-
@InjectMocks的作用:标记应执行注入的字段(指此对象内的字段应该被自动的注入,注入的值来自@Mock或@Spy注解的字段)。
- 允许快速的mock和spy注入。
- 最大限度地减少重复的mock和spy注入代码。
【太长了这一段可以不看:主要说了@InjectMocks注解的对象如何自动注入@Mock和@Spy字段】Mockito 将尝试仅通过构造函数注入、setter 注入或属性注入依次注入mock对象,如下所述。如果以下任一策略失败,则 Mockito不会报告失败;即您必须自己提供依赖项。
-
构造函数注入:选择最大的构造函数(方法参数最多),然后使用仅在测试类中声明的mock来解析参数。如果使用构造函数成功创建了对象,则 Mockito 不会尝试其他策略。Mockito 决定不破坏具有参数构造函数的对象。
注意:如果找不到参数,则传递 null。如果需要不可mock的类型,则不会发生构造函数注入。在这些情况下,您必须自己满足依赖项。
-
属性设置器注入(setter方法):Mockito 将首先按类型解析(如果单个类型匹配则不管名称如何都会发生注入),然后,如果有多个相同类型的属性,则通过属性名称和mock名称匹配注入。
注意1:如果你有相同类型(或类型擦除后相同)的属性,最好用匹配的属性命名所有@Mock注解的字段,否则 Mockito 可能会产生混淆并且不会注入。
注意2:如果@InjectMocks 对象之前没有初始化并且有一个无参数构造函数,那么它将用这个构造函数初始化。
-
字段注入:Mockito 将首先按类型解析(如果单个类型匹配则不管名称如何都会发生注入),然后,如果有多个相同类型的属性,则通过字段名称和mock对象名称的匹配进行注入。
注意1:如果你有相同类型(或类型擦除后相同)的字段,最好用匹配的字段命名所有@Mock注解的字段,否则 Mockito 可能会产生淆并且不会注入。
注意2:如果@InjectMocks 对象之前没有初始化并且有一个无参数构造函数,那么它将用这个构造函数初始化。
例子:
public class ArticleManagerTest extends SampleBaseTestCase { @Mock private ArticleCalculator calculator; @Mock(name = "database") private ArticleDatabase dbMock; // note the mock name attribute @Spy private UserProvider userProvider = new ConsumerUserProvider(); @InjectMocks private ArticleManager manager; @Test public void shouldDoSomething() { manager.initiateArticle(); verify(database).addListener(any(ArticleListener.class)); } } public class SampleBaseTestCase { private AutoCloseable closeable; @Before public void openMocks() { closeable = MockitoAnnotations.openMocks(this); } @After public void releaseMocks() throws Exception { closeable.close(); } } 复制代码
在上面的例子中,
@InjectMocks
注解的字段ArticleManager
只能有一个参数化的构造函数或一个无参数的构造函数,或者两者都有。所有这些构造函数的可见性可以是package-protect、protected或private的,但是 Mockito 不能实例化内部类、本地类、抽象类,当然还有接口。 也要注意私有嵌套静态类。同样是 setter 或字段,它们的可见性声明可以是private的,Mockito 将通过反射看到它们。但是,静态或final字段将被忽略。
所以在需要注入的领域,例如构造函数注入会在这里发生:
public class ArticleManager { ArticleManager(ArticleCalculator calculator, ArticleDatabase database) { // parameterized constructor } } 复制代码
属性setter注入将在这里发生:
public class ArticleManager { // no-arg constructor ArticleManager() { } // setter void setDatabase(ArticleDatabase database) { } // setter void setCalculator(ArticleCalculator calculator) { } } 复制代码
此处将使用字段注入:
public class ArticleManager { private ArticleDatabase database; private ArticleCalculator calculator; } 复制代码
最后,在这种情况下,不会发生注入:
public class ArticleManager { private ArticleDatabase database; private ArticleCalculator calculator; ArticleManager(ArticleObserver observer, boolean flag) { // observer is not declared in the test above. // flag is not mockable anyway } } 复制代码
再次注意,@InjectMocks 只会注入使用 @Spy 或 @Mock 注解创建的mocks/spies对象。
必须调用**
MockitoAnnotations.openMocks(this)
**方法来初始化带注解的对象。在上面的例子中,openMocks()
在测试基类的@Before (JUnit4) 方法中调用。对于 JUnit3,openMocks()
可以转到基类的setup()
方法。 **相反,**您也可以将 openMocks() 放在 JUnit 运行程序 (@RunWith) 中或使用内置的 MockitoJUnitRunner. 另外,请确保在使用相应的钩子处理测试类后释放任何mock。Mockito 不是依赖注入框架,不要指望这个快速实用程序可以注入复杂的对象图,无论是mocks/spies对象还是真实对象。
-
4:参考
- Mockito官方文档中的:
- 9.mocks的简单创建方式--@Mock注解
- 16.真正的部分mock(自 1.8.0 起)
- 21.新注解:@Captor, @Spy, @InjectMocks(自 1.8.3 起)
- 23.使用@Spies, @InjectMocks自动实例化对象并具有良好的构造函数注入(1.9.0以后)
- 30.监视或mock抽象类(自 1.10.12 起,在 2.7.13 和 2.7.14 中进一步增强)
- 32.对深存根(deep stubs)更好的通用支持(自 1.10.0 起)
- 33.Mockito JUnit rule(自 1.10.17 起)
- 37.Java 8 自定义Answer支持(自 2.1.0 起)
- 38.元数据和泛型类型的保留(自 2.1.0 起)
- 39.mock final类、枚举和 final方法(自 2.1.0 起)
- 48.mock静态方法(自 3.4.0 起)
- 49.mock对象构造(自 3.5.0 起)
5:常见问题
- mock对象和spy对象有什么区别?
- mock对象的默认返回类型的空值(可以配置返回策略),其方法被调用时不会执行实际的代码逻辑而是直接返回。
- spy对象是默认执行实际方法逻辑并返回,可以对spy对象的某个方法进行存根以指定返回值且避免调用此方法实际逻辑。
- mock对象的返回值策略(Answer策略)有那些?如何配置?
- 上文已介绍,请查阅。
- 对spy对象的某个方法进行存根时有什么特殊要求吗?为什么我有时明明做了存根操作,方法的实际逻辑还是会被调用?
- 存根要求:使用doXXX(x).when(spy).m1()的方式而不是whenXXX(spy.m1()).thenXXX(x)的方式。
- 实际逻辑为什么会被调用:因为使用了whenXXX(spy.m1()).thenXXX(x)存根方式。具体上文已介绍。请查阅。
- 创建这一系列测试相关的对象的最佳实践是什么?
- 使用@InjectMocks注解,同时结合在类上使用注解@RunWith(MockitoJUnitRunner.class)而不是在@Before方法中使用MockitoAnnotations.openMocks(testClass)的方式创建被测对象。我们的原则是尽量使用注解的方式创建测试相关的对象。
- 使用@Mock而不是Mockito.mock()方法创建mock对象。
- 使用@Spy而不是Mockito.spy()方法创建spy对象。当然在某个具体测试方法内你发现@Spy不能方便的满足你的需求时请使用Mockito.spy()的方式。
二:存根方法调用
-
定义存根方法的方式:
-
Mockito.when(foo.sum()).thenXXX(...);
- 即对foo.sum()方法存根。
- 注意:
- foo对象应该是一个mock对象。spy对象不建议使用此方式进行存根。因为当代码执行到when(foo.sum())时。foo.sum()方法会首先执行。导致sum()方法的实际代码逻辑被执行。(sum()的实际代码逻辑是否会被执行要看被spy对象的类型,当被spy对象是一个mock对象或者接口时不会执行-这些类型也没有实际代码逻辑可以执行。当被spy对象一个具体的对象时则实际代码逻辑会被执行)
-
Mockito.doXXX(...).when(foo).sum();
- 即对foo.sum()方法存根。
- 可以存根void方法。
- foo对象可以是一个mock对象,也可以是一个spy对象。
-
Mockito.doXXX(....).when(foo.sum());
-
你会得到一个异常,即不应该使用这种方式!
-
org.mockito.exceptions.misusing.UnfinishedStubbingException: Unfinished stubbing detected here: -> at c.FooTest.verifyTest(FooTest.java:23) E.g. thenReturn() may be missing. Examples of correct stubbing: when(mock.isOk()).thenReturn(true); when(mock.isOk()).thenThrow(exception); doThrow(exception).when(mock).someVoidMethod(); Hints: 1. missing thenReturn() 2. you are trying to stub a final method, which is not supported 3. you are stubbing the behaviour of another mock inside before 'thenReturn' instruction is completed 复制代码
-
-
-
定义返回值的方式:
-
then_xxx方法 do_XXX方法 功能 then(Answer<?> answer) doAnswer(Answer answer) 返回值使用自定义的Answer策略。 thenAnswer(Answer<?> answer) 同上 同上。 thenReturn(T value) doReturn(Object toBeReturned) 直接指定返回值。 thenReturn(T value, T... values) doReturn(Object toBeReturned, Object... toBeReturnedNext) 直接指定返回值,可以定义多个返回值。第一次调用到存根方法返回第一个返回值。以此类推。超过返回值数量的调用返回参数的最后一个返回值。 thenCallRealMethod() doCallRealMethod() 调用实际的代码逻辑。不指定返回值。 thenThrow(Throwable... throwables) doThrow(Throwable... toBeThrown) 调用到存根方法时抛出异常。 同上 doThrow(Class<? extends Throwable> toBeThrown) 调用到存根方法时抛出异常。可以定义多个异常。第一次调用到存根方法返回第一个异常。以此类推。超过异常数量的调用返回参数的最后一个异常。 同上 doThrow(Class<? extends Throwable> toBeThrown, Class<? extends Throwable>... toBeThrownNext) 同上。 无对应方法 doNothing() void方法使用的存根方式。
-
-
参数匹配器
- 参数匹配器一般使用在存根方法的调用时。
- 参数匹配器也可以使用在方法的验证时。
- 3:参数匹配
- 有关于参数匹配器的介绍
-
示例
- 2:添加一些存根(stub):指定mock对象方法调用的返回值
- 3个注意事项
- 5.存根有异常的void方法
- 10.存根连续调用(iterator-style stubbing)
- 11.使用回调进行存根
- 12.doReturn()| doThrow()| doAnswer()| doNothing()| doCallRealMethod()方法族
- 13.监视真实对象:使用spy
- 包含了一些spy使用时的提示
- 14.更改未存根调用的默认返回值(自 1.7 起)
- 16.真正的部分mock(自 1.8.0 起)
- 使用spy或者mock。
- thenCallRealMethod()方法。
- 2:添加一些存根(stub):指定mock对象方法调用的返回值
-
注意事项:
- TODO
三:验证方法调用
验证方法:
方法是否被调用/方法的调用的次数
atLeast(int minNumberOfInvocations)
允许至少 x 调用的验证。atLeastOnce()
允许至少一次调用的验证。atMost(int maxNumberOfInvocations)
允许最多 x 次调用的验证。atMostOnce()
允许最多一次调用的验证。never()
times(0)
的别名,见times(int) 。only()
允许检查给定的方法是否只调用一次。times(int wantedNumberOfInvocations)
允许验证调用的确切次数。verify(T mock)
验证某些行为发生过一次。verify(T mock, VerificationMode mode)
验证某些行为至少发生过一次/确切的次数/从未发生过。verifyNoInteractions(Object... mocks)
验证给定的模拟上没有发生交互。verifyNoMoreInteractions(Object... mocks)
检查任何给定的模拟是否有任何未经验证的交互。
方法执行的时间
after(long millis)
在给定的毫秒数后将触发验证,允许测试异步代码。timeout(long millis)
验证将一遍又一遍地触发,直到给定的毫秒数,允许测试异步代码。
调用顺序验证
calls(int wantedNumberOfInvocations)
允许按顺序进行非贪婪调用的验证。inOrder(Object... mocks)
创建InOrder对象,允许按顺序验证mock的对象。
示例:
- 1:验证mock对象的行为(方法是否被调用以及调用返回值)
- 4:验证确切的调用次数/至少调用x次/从未调用
- 6:调用顺序验证
- 7.确保在mock对象从未发生交互
- 8.寻找多余的调用
- 15.为进一步的断言捕获参数(自 1.8.0 起)
- 一些关于捕获参数进行断言的警告。
- 22.超时验证(自 1.8.5 起)
- 35.自定义验证失败信息(自 2.1.0 起)
- 40. 使用“更严格”的 Mockito 提高生产力和编写更简明的测试(自 2.+ 起)
验证方法参考:
修饰符和类型 | 方法和说明 |
---|---|
static VerificationAfterDelay | after(long millis) 在给定的毫秒数后将触发验证,允许测试异步代码。 |
static VerificationMode | atLeast(int minNumberOfInvocations) 允许至少 x 调用的验证。 |
static VerificationMode | atLeastOnce() 允许至少一次调用的验证。 |
static VerificationMode | atMost(int maxNumberOfInvocations) 允许最多 x 次调用的验证。 |
static VerificationMode | atMostOnce() 允许最多一次调用的验证。 |
static VerificationMode | calls(int wantedNumberOfInvocations) 允许按顺序进行非贪婪调用的验证。 |
static Object[] | ignoreStubs(Object... mocks) 为了验证,忽略给定mock的存根方法。 |
static InOrder | inOrder(Object... mocks) 创建InOrder对象,允许按顺序验证mock的对象。 |
static LenientStubber | lenient() 宽松存根,绕过“严格存根”验证(请参阅参考资料Strictness.STRICT_STUBS)。 |
static VerificationMode | never() times(0) 的别名,见times(int) |
static VerificationMode | only() 允许检查给定的方法是否只调用一次。 |
static <T> void | reset(T... mocks) 聪明 Mockito 用户几乎不使用此功能,因为他们知道这可能是测试不佳的迹象。 |
static VerificationWithTimeout | timeout(long millis) 验证将一遍又一遍地触发,直到给定的毫秒数,允许测试异步代码。 |
static VerificationMode | times(int wantedNumberOfInvocations) 允许验证调用的确切次数。 |
static void | validateMockitoUsage() 首先,如果有任何问题,我鼓励您阅读 Mockito FAQ: github.com/mockito/moc… |
static <T> T | verify(T mock) 验证某些行为发生过一次。 |
static <T> T | verify(T mock, VerificationMode mode) 验证某些行为至少发生过一次/确切的次数/从未发生过。 |
static void | verifyNoInteractions(Object... mocks) 验证给定的模拟上没有发生交互。 |
static void | verifyNoMoreInteractions(Object... mocks) 检查任何给定的模拟是否有任何未经验证的交互。 |
四:Mockito中有用的操作
-
17.重置mock(自 1.8.0 起)
- Mockito会忘掉了所有的交互和存根。
-
18.故障排除和验证框架的使用(自 1.8.0 起)
-
19.行为驱动开发的别名(自 1.8.0 起)
-
20.可序列化的mock(自 1.8.1 起)
-
24.单行存根(自 1.9.0 起)
-
25.忽略存根的验证(自 1.9.0 起)
-
26.mockingDetails(2.2.x 改进)
-
27.将调用委托给真实对象(自 1.9.5 起)
-
28.MockMaker API(从 1.9.5 开始)
-
29.BDD 风格验证(自 1.10.0 起)
-
31.Mockito 模拟可以跨类加载器序列化/反序列化(自 1.10.0 起)
-
34.切换插件的启用或禁用(15年10月1日以来)
-
36.Java 8 Lambda 匹配器支持(自 2.1.0 起)
-
41. 用于框架集成的高级公共 API(自 2.10.+ 起)
-
42. 用于集成的新 API:监听验证开始事件(自 2.11.+ 起)
-
43. 用于集成的新 API:可用于测试框架的MockitoSession(自 2.15.+ 起)
-
44. 已弃用,org.mockito.plugins.InstantiatorProvider因为它会泄漏内部 API。它被替换为org.mockito.plugins.InstantiatorProvider2 (Since 2.15.4)
-
45.新的 JUnit Jupiter (JUnit5+) 扩展
-
46. 新的Mockito.lenient()和MockSettings.lenient()的方法(自2.20.0)
-
47.用于清除内联mock中mock状态的新 API(自 2.25.0 起)
五:参考
Mockito Javadoc参考:
修饰符和类型 | 方法和说明 |
---|---|
static VerificationAfterDelay | after(long millis) 在给定的毫秒数后将触发验证,允许测试异步代码。 |
static VerificationMode | atLeast(int minNumberOfInvocations) 允许至少 x 调用的验证。 |
static VerificationMode | atLeastOnce() 允许至少一次调用的验证。 |
static VerificationMode | atMost(int maxNumberOfInvocations) 允许最多 x 次调用的验证。 |
static VerificationMode | atMostOnce() 允许最多一次调用的验证。 |
static VerificationMode | calls(int wantedNumberOfInvocations) 允许按顺序进行非贪婪调用的验证。 |
static void | clearAllCaches() 清除所有mock、类型缓存和检测。 |
static <T> void | clearInvocations(T... mocks) 仅在存根不重要时使用此方法清除调用。 |
static VerificationMode | description(String description) 添加要在验证失败时打印的说明。 |
static Stubber | doAnswer(Answer answer) 当你想要和通用的 Answer 一起存根void方法时使用doAnswer() 。 |
static Stubber | doCallRealMethod() 使用doCallRealMethod() 时会调用(执行)真正的方法。 |
static Stubber | doNothing() 使用doNothing() 设置void方法什么也不做。 |
static Stubber | doReturn(Object toBeReturned) 在那些极少数情况下,你不能使用when(Object)时,使用doReturn() 。 |
static Stubber | doReturn(Object toBeReturned, Object... toBeReturnedNext) 与doReturn(Object)相同,但可以设置连续的返回值。 |
static Stubber | doThrow(Class<? extends Throwable> toBeThrown) 要存根void方法并抛出异常时使用doThrow() 。 |
static Stubber | doThrow(Class<? extends Throwable> toBeThrown, Class<? extends Throwable>... toBeThrownNext) 与doThrow(Class)相同,但可以设置连续的异常。 |
static Stubber | doThrow(Throwable... toBeThrown) 要存根void方法并抛出异常时使用doThrow() ,支持连续抛出异常。 |
static MockitoFramework | framework() 为高级用户或框架集成商提供。 |
static Object[] | ignoreStubs(Object... mocks) 为了验证,忽略给定mock的存根方法。 |
static InOrder | inOrder(Object... mocks) 创建InOrder对象,允许按顺序验证mock的对象。 |
static LenientStubber | lenient() 宽松存根,绕过“严格存根”验证(请参阅 参考资料Strictness.STRICT_STUBS)。 |
static <T> T | mock(Class<T> classToMock) 创建给定类或接口的mock对象。 |
static <T> T | mock(Class<T> classToMock, Answer defaultAnswer) 使用指定的Answer策略创建mock以交互。 |
static <T> T | mock(Class<T> classToMock, MockSettings mockSettings) 创建具有一些非标准设置的mock。 |
static <T> T | mock(Class<T> classToMock, String name) 指定mock名称。 |
static <T> MockedConstruction<T> | mockConstruction(Class<T> classToMock) 为给定类的所有构造器创建线程本地mock控制器。 |
static <T> MockedConstruction<T> | mockConstruction(Class<T> classToMock, java.util.function.Function<MockedConstruction.Context,MockSettings> mockSettingsFactory) 为给定类的所有构造器创建线程本地mock控制器。 |
static <T> MockedConstruction<T> | mockConstruction(Class<T> classToMock, java.util.function.Function<MockedConstruction.Context,MockSettings> mockSettingsFactory, MockedConstruction.MockInitializer<T> mockInitializer) 为为给定类的所有构造器创建线程本地mock控制器。 |
static <T> MockedConstruction<T> | mockConstruction(Class<T> classToMock, MockedConstruction.MockInitializer<T> mockInitializer) 为给定类的所有构造器创建线程本地mock控制器。 |
static <T> MockedConstruction<T> | mockConstruction(Class<T> classToMock, MockSettings mockSettings) 为给定类的所有构造器创建线程本地mock控制器。 |
static <T> MockedConstruction<T> | mockConstruction(Class<T> classToMock, MockSettings mockSettings, MockedConstruction.MockInitializer<T> mockInitializer) 为给定类的所有构造器创建线程本地mock控制器。 |
static <T> MockedConstruction<T> | mockConstructionWithAnswer(Class<T> classToMock, Answer defaultAnswer, Answer... additionalAnswers) 为给定类的所有构造器创建线程本地mock控制器。 |
static MockingDetails | mockingDetails(Object toInspect) 返回一个 MockingDetails 实例,该实例允许检查特定对象以获取 Mockito 相关信息。 |
static MockitoSessionBuilder | mockitoSession() MockitoSession 是一个可选的、强烈推荐的功能,它通过消除样板代码和添加额外的验证来帮助推动更清晰的测试。 |
static <T> MockedStatic<T> | mockStatic(Class<T> classToMock) 为给定类或接口的所有静态方法创建线程本地mock控制器。 |
static <T> MockedStatic<T> | mockStatic(Class<T> classToMock, Answer defaultAnswer) 为给定类或接口的所有静态方法创建线程本地mock控制器。 |
static <T> MockedStatic<T> | mockStatic(Class<T> classToMock, MockSettings mockSettings) 为给定类或接口的所有静态方法创建线程本地mock控制器。 |
static <T> MockedStatic<T> | mockStatic(Class<T> classToMock, String name) 为给定类或接口的所有静态方法创建线程本地mock控制器。 |
static VerificationMode | never() times(0) 的别名,见times(int) |
static VerificationMode | only() 允许检查给定的方法是否只调用一次。 |
static <T> void | reset(T... mocks) 聪明 Mockito 用户几乎不使用此功能,因为他们知道这可能是测试不佳的迹象。 |
static <T> T | spy(Class<T> classToSpy) 请参阅 的文档spy(Object)。 |
static <T> T | spy(T object) 创建真实对象的监视。 |
static VerificationWithTimeout | timeout(long millis) 验证将一遍又一遍地触发,直到给定的毫秒数,允许测试异步代码。 |
static VerificationMode | times(int wantedNumberOfInvocations) 允许验证调用的确切次数。 |
static void | validateMockitoUsage() 首先,如果有任何问题,我鼓励您阅读 Mockito FAQ:https : //github.com/mockito/mockito/wiki/FAQ |
static <T> T | verify(T mock) 验证某些行为发生过一次。 |
static <T> T | verify(T mock, VerificationMode mode) 验证某些行为至少发生过一次/确切的次数/从未发生过。 |
static void | verifyNoInteractions(Object... mocks) 验证给定的模拟上没有发生交互。 |
static void | verifyNoMoreInteractions(Object... mocks) 检查任何给定的模拟是否有任何未经验证的交互。 |
static void | verifyZeroInteractions(Object... mocks) 已弃用。 从 3.0.1 开始。请将您的代码迁移到verifyNoInteractions(Object...) |
static <T> OngoingStubbing<T> | when(T methodCall) 创建方法的存根。 |
static MockSettings | withSettings() 允许使用其他mock设置进行mock创建。 |
Mockito.after(100);
Mockito.atLeast();
Mockito.atLeastOnce();
Mockito.atMost();
Mockito.atMostOnce();
Mockito.calls();
Mockito.clearAllCaches();
Mockito.clearInvocations();
Mockito.description();
Mockito.doAnswer();
Mockito.doCallRealMethod();
Mockito.doNothing();
Mockito.doReturn();
Mockito.doReturn(null,null);
Mockito.doThrow(Object.class);
Mockito.doThrow(null,null);
Mockito.doThrow(new Exception())
Mockito.framework()
Mockito.ignoreStubs()
Mockito.inOrder()
Mockito.lenient()
Mockito.mock(null)
Mockito.mock(null,null)
Mockito.mock(null, new MockSettings())
Mockito.mock(Object.class,"xx")
Mockito.mockConstruction(6)
Mockito.mockConstructionWithAnswer()
Mockito.mockingDetails()
Mockito.mockitoSession()
Mockito.mockStatic(4)
Mockito.never()
Mockito.only()
Mockito.reset();
Mockito.spy(2)
Mockito.timeout()
Mockito.times()
Mockito.validateMockitoUsage();
Mockito.verify(2)
Mockito.verifyNoInteractions();
Mockito.verifyNoMoreInteractions();
Mockito.verifyZeroInteractions();
Mockito.when()
Mockito.withSettings()
作者:汪进
链接:https://juejin.cn/post/6975525979418525709
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
最后
以上就是兴奋大象为你收集整理的mockito的使用四:Mockito中有用的操作五:参考的全部内容,希望文章能够帮你解决mockito的使用四:Mockito中有用的操作五:参考所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复