如何在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.mockito : mockito-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
。