如何在JUnit5中使用Mockito

如何使用Mockito和JUnit 5进样?

在JUnit4中,我可以使用@RunWith(MockitoJUnitRunner.class) Annotation。 在JUnit5中没有@RunWith Annotation?

使用Mockito有不同的方法 – 我将逐一介绍它们。

手动

无论JUnit版本(或测试框架)如何,使用Mockito::mock mock手动创建Mockito::mock可以正常工作。

基于注释

使用@Mock -annotation和相应的MockitoAnnotations::initMocks调用来创建 MockitoAnnotations::initMocks工作无论JUnit版本(或测试框架),但Java 9可能会干扰这里,具体取决于测试代码是否在模块中或不)。

Mockito扩展

JUnit 5有一个强大的扩展模型 ,Mockito最近在组/工件ID org.mockitomockito-junit-jupiter下发布了一个。

您可以通过将@ExtendWith(MockitoExtension.class)添加到测试类并使用@Mock注释@ExtendWith(MockitoExtension.class)字段来应用扩展。 来自MockitoExtension的JavaDoc:

 @ExtendWith(MockitoExtension.class) public class ExampleTest { @Mock private List list; @Test public void shouldDoSomething() { list.add(100); } } 

Mockito文档对扩展仍然有点沉默。

没有规则,没有跑步者

JUnit 4规则和运行器在JUnit 5中不起作用,因此不能使用MockitoRule和Mockito运行器。

使用Mockito的MockitoExtension 。 扩展包含在一个新的工件mockito-junit-jupiter

  org.mockito mockito-junit-jupiter 2.18.0 test  

它允许您像使用JUnit 4一样编写测试:

 import org.mockito.junit.jupiter.MockitoExtension; import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(MockitoExtension.class) class MyTest { @Mock private Foo foo; @InjectMocks private Bar bar; // constructor injection ... } 

您必须使用新的@ExtendWith注释。

不幸的是,尚未发布任何扩展。 在github上,您可以看到扩展的beta实现。 作为示例演示测试 。

有不同的方法,但更清洁的方式,也尊重JUnit 5的理念是为Mockito创建一个org.junit.jupiter.api.extension.Extension

1) 手动创建模拟会失去额外的Mockito检查的好处,以确保您正确使用框架。

2)在每个测试类中调用MockitoAnnotations.initMocks(this)是我们可以避免的样板代码。
在抽象类中进行此设置也不是一个好的解决方案。
它将每个测试类耦合到基类。
如果那时你有充分的理由需要一个新的基础测试类,那么你将完成一个3级的层次结构。 请避免这样做。

3)测试规则是JUnit 4的特异性。
甚至没想到这一点。
文档清楚地表明了这一点:

但是,如果您打算为JUnit 5开发新的扩展,请使用JUnit Jupiter的新扩展模型,而不是基于规则的JUnit 4模型。

4)Test Runner实际上不是扩展JUnit 5框架的方法。
由于JUnit 5 Extensions,JUnit 5通过提供编写测试的扩展模型简化了JUnit 4 Runners的地狱。
甚至没想到这一点。

所以赞成org.junit.jupiter.api.extension.Extension方式。


编辑:实际上,Mockito捆绑了一个木星扩展: mockito-junit-jupiter

然后,使用起来非常简单:

 import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) public class FooTest { ... } 

这是乔纳森的优秀答案的补充。

通过添加mockito-junit-jupiter工件作为依赖项,使用@ExtendWith(MockitoExtension.class)在执行测试时产生以下exception:

java.lang.NoSuchMethodError:org.junit.platform.commons.support.AnnotationSupport.findAnnotation(Ljava / util / Optional; Ljava / lang / Class;)Ljava / util / Optional;

问题是mockito-junit-jupiter依赖于两个独立的库。 例如对于mockito-junit-jupiter:2.19.0

  org.mockito mockito-core 2.19.0 compile   org.junit.jupiter junit-jupiter-api 5.1.0 runtime  

问题是我使用junit-jupiter-api:5.0.1

因此,当junit-jupiter-api经常在API方面移动时,请确保您依赖于mockito-junit-jupiter所依赖的相同版本的junit-jupiter-api