27. 委托调用真实实例 (Since 1.9.5)

使用常规的 spy API 去 mock 或者 spy 一个对象很困难时可以用 delegate 来 spy 或者 mock 对象的某一部分。 从 Mockito 的 1.10.11 版本开始, delegate 有可能和 mock 的类型相同也可能不同。如果不是同一类型, delegate 类型需要提供一个匹配方法否则就会抛出一个异常。下面是关于这个特性的一些用例:

  • 带有 interface 的 final 类
  • 已经自定义代理的对象
  • 带有 finalize 方法的特殊对象,就是避免重复执行。

和常规 spy 的不同:

  • 标准的 spy (spy(Object)) 包含被 spy 实例的所有状态信息,方法在 spy 对象上被调用。被 spy 的对象只在 mock 创建时被用来拷贝状态信息。如果你通过标准 spy 调用一个方法,这个 spy 会调用其内部的其他方法记录这次操作, 以便后面验证使用。等效于存根 (stubbed)操作。

  • mock delegates 只是简单的把所有方法委托给 delegate。delegate 一直被当成它代理的方法使用。如果你 从一个 mock 调用它被委托的方法,它会调用其内部方法,这些调用不会被记录,stubbing 在这里也不会生效。 Mock 的 delegates 相对于标准的 spy 来说功能弱了很多,不过在标准 spy 不能被创建的时候很有用。

更多信息可以看这里 AdditionalAnswers.delegatesTo(Object).


28. MockMaker API (Since 1.9.5)

为了满足用户的需求和 Android 平台使用。Mockito 现在提供一个扩展点,允许替换代理生成引擎。默认情况下,Mockito 使用 cglib 创建动态代理。

这个扩展点是为想要扩展 Mockito 功能的高级用户准备的。比如,我们现在就可以在 dexmaker 的帮助下使用 Mockito 测试 Android。

更多的细节,原因和示例请看 MockMaker 的文档。


29. (new) BDD 风格的验证 (Since 1.10.0)

开启 Behavior Driven Development (BDD) 风格的验证可以通过 BBD 的关键词 then 开始验证。

  1. given(dog.bark()).willReturn(2);
  2. // when
  3. ...
  4. then(person).should(times(2)).ride(bike);

更多信息请查阅 BDDMockito.then(Object) .


30. (new) Spying 或 mocking 抽象类 (Since 1.10.12)

现在可以方便的 spy 一个抽象类。注意,过度使用 spy 或许意味着代码的设计上有问题。(see spy(Object)).

之前,spying 只可以用在实例对象上。而现在新的 API 可以在创建一个 mock 实例时使用构造函数。这对 mock 一个抽象类来说是很重要的,这样使用者就不必再提供一个抽象类的实例了。目前的话只支持无参构造函数, 如果你认为这样还不够的话欢迎向我们反馈。

  1. //convenience API, new overloaded spy() method:
  2. SomeAbstract spy = spy(SomeAbstract.class);
  3. //Robust API, via settings builder:
  4. OtherAbstract spy = mock(OtherAbstract.class, withSettings()
  5. .useConstructor().defaultAnswer(CALLS_REAL_METHODS));
  6. //Mocking a non-static inner abstract class:
  7. InnerAbstract spy = mock(InnerAbstract.class, withSettings()
  8. .useConstructor().outerInstance(outerInstance).defaultAnswer(CALLS_REAL_METHODS));

更多信息请见 MockSettings.useConstructor() .


31. (new) Mockito mocks 可以通过 classloaders 序列化/反序列化 (Since 1.10.0)

Mockito 通过 classloader 引入序列化。和其他形式的序列化一样,所有 mock 层的对象都要被序列化, 包括 answers。因为序列化模式需要大量的工作,所以这是一个可选择设置。

  1. // 常规的 serialization
  2. mock(Book.class, withSettings().serializable());
  3. // 通过 classloaders 序列化
  4. mock(Book.class, withSettings().serializable(ACROSS_CLASSLOADERS));

更多信息请查看 MockSettings.serializable(SerializableMode).


32. (new) Deep stubs 更好的泛型支持 (Since 1.10.0)

Deep stubbing 现在可以更好的查找类的泛型信息。这就意味着像这样的类 不必去 mock 它的行为就可以使用。

  1. class Lines extends List<Line> {
  2. // ...
  3. }
  4. lines = mock(Lines.class, RETURNS_DEEP_STUBS);
  5. // Now Mockito understand this is not an Object but a Line
  6. Line line = lines.iterator().next();

请注意,大多数情况下 mock 返回一个 mock 对象是错误的。


33. (new) Mockito JUnit rule (Since 1.10.17)

Mockito 现在提供一个 JUnit rule。目前为止,有两种方法可以初始化 fields ,使用 Mockito 提供的注解比如 @Mock, @Spy, @InjectMocks 等等。

现在你可以选择使用一个 rule:

  1. @RunWith(YetAnotherRunner.class)
  2. public class TheTest {
  3. @Rule public MockitoRule mockito = MockitoJUnit.rule();
  4. // ...
  5. }

更多信息到这里查看 MockitoJUnit.rule().


34. (new) 开启和关闭 plugins (Since 1.10.15)

这是一个测试特性,可以控制一个 mockito-plugin 开启或者关闭。详情请查看 PluginSwitch


35. 自定义验证失败信息 (Since 2.0.0)

允许声明一个在验证失败时输出的自定义消息 示例:

  1. // will print a custom message on verification failure
  2. verify(mock, description("This will print on failure")).someMethod();
  3. // will work with any verification mode
  4. verify(mock, times(2).description("someMethod should be called twice")).someMethod();