如何在 Mockito 和 JUnit 5 中使用注入?
在 JUnit4 中,我可以只使用@RunWith(MockitoJUnitRunner.class)
注解。在 JUnit5 中是没有@RunWith
Annotation 的吗?
如何在 Mockito 和 JUnit 5 中使用注入?
在 JUnit4 中,我可以只使用@RunWith(MockitoJUnitRunner.class)
注解。在 JUnit5 中是没有@RunWith
Annotation 的吗?
有多种使用 Mockito 的方法——我将一一介绍。
Mockito::mock
无论 JUnit 版本(或相关的测试框架)如何,都可以手动创建模拟。
无论 JUnit 版本如何(或测试框架,但 Java 9 可能会在这里干扰,这取决于测试代码是否在模块中结束),使用@Mock -annotation 和相应的调用来MockitoAnnotations::initMocks
创建模拟都可以工作。
JUnit 5 有一个强大的扩展模型,Mockito 最近在组/工件 ID org.mockito下发布了一个:mockito-junit-jupiter。
您可以通过添加@ExtendWith(MockitoExtension.class)
到测试类并使用@Mock
. 来自MockitoExtension
的 JavaDoc:
@ExtendWith(MockitoExtension.class)
public class ExampleTest {
@Mock
private List list;
@Test
public void shouldDoSomething() {
list.add(100);
}
}
MockitoExtension 文档描述了实例化模拟的其他方法,例如使用构造函数注入(如果您在测试类中引用 final 字段)。
JUnit 4 规则和运行器在 JUnit 5 中不起作用,因此不能使用MockitoRule
和Mockito 运行器。
使用 Mockito 的MockitoExtension
. 扩展包含在一个新的工件中mockito-junit-jupiter
:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
它允许您像使用 JUnit 4 一样编写测试:
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
@ExtendWith(MockitoExtension.class)
class MyTest {
@Mock
private Foo foo;
@InjectMocks
private Bar bar; // constructor injection
...
}
有不同的方法可以做,但更清洁的方法也尊重 JUnit 5 的理念是 org.junit.jupiter.api.extension.Extension
为 Mockito 创建一个。
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)
执行测试时使用产生以下异常:
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
:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.19.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.1.0</version>
<scope>runtime</scope>
</dependency>
问题是我用过junit-jupiter-api:5.0.1
。
因此,junit-jupiter-api
在 API 方面仍然经常移动,请确保您所依赖的版本与junit-jupiter-api
所mockito-junit-jupiter
依赖的版本相同。