如何在Mockito和JUnit 5中使用注入?
在JUnit4中,我可以只使用@RunWith(MockitoJUnitRunner.class)
Annotation。在JUnit5中没有@RunWith
注释吗?
如何在Mockito和JUnit 5中使用注入?
在JUnit4中,我可以只使用@RunWith(MockitoJUnitRunner.class)
Annotation。在JUnit5中没有@RunWith
注释吗?
Answers:
有多种使用Mockito的方法-我将一一介绍。
Mockito::mock
不论JUnit版本是什么(或测试框架),都可以使用Works手动创建模拟。
使用@Mock -annotation和相应的调用MockitoAnnotations::initMocks
来创建嘲笑的作品无论JUnit版本(或测试框架,对于这个问题,但测试代码是否在一个模块中最终还是不是Java 9干扰可能在这里,取决于)。
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文档描述了实例化模拟的其他方式,例如,通过构造函数注入(如果您在测试类中对最终字段进行了重载)。
JUnit 4规则和运行器在JUnit 5中不起作用,因此不能使用MockitoRule
和Mockito运行器。
@Test
需要公开还是“私有包”足够好?
使用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
...
}
@ExtendWith(MockitoExtension.class)
相当于@RunWith(MockitoJUnitRunner.class)
JUnit4
有许多不同的方法可以做,但是更org.junit.jupiter.api.extension.Extension
简洁的方法也符合JUnit 5的理念,它为Mockito 创建了一个 方法。
1)手动创建模拟会使其他Mockito检查无法确保您正确使用框架的好处。
2)调用MockitoAnnotations.initMocks(this)
每个测试类都是我们可以避免的样板代码。
并且在抽象类中进行此设置也不是一个好的解决方案。
它将每个测试类耦合到一个基础类。
如果出于某种原因您需要一个新的基础测试类,那么您将获得一个3级类层次结构。请避免那样。
3)测试规则是JUnit 4的特异性。
甚至不用考虑。
并且文档对此很清楚:
但是,如果您打算为JUnit 5开发新的扩展,请使用JUnit Jupiter的新扩展模型,而不是基于规则的JUnit 4模型。
4)Test Runner实际上不是扩展JUnit 5框架的方法。
通过使用JUnit 5扩展,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 {
...
}
这是乔纳森(Jonathan)出色回答的补充。
通过添加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
要看。
mockito-junit-jupiter
拉正确版本的junit-jupiter-api
?
mockito-junit-jupiter:2.19.0
。而JUnit Jupiter版本以开头5
。mockito-junit-jupiter应该在其工件标识符中指定了两件事(Mockito版本和JUnit Jupiter版本),以使事情更清楚。例如mockito-junit-jupiter-5.1:2.19.0
,该库是为JUnit Jupiter 5.1设计的。
MockitoExtension
在mockito-core
3.0.0版本中似乎不存在。
mockito-junit-jupiter