如何在JUnit5中使用Mockito


Answers:


144

有多种使用Mockito的方法-我将一一介绍。

手动地

Mockito::mock不论JUnit版本是什么(或测试框架),都可以使用Works手动创建模拟。

基于注释

使用@Mock -annotation和相应的调用MockitoAnnotations::initMocks创建嘲笑的作品无论JUnit版本(或测试框架,对于这个问题,但测试代码是否在一个模块中最终还是不是Java 9干扰可能在这里,取决于)。

Mockito扩展

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中不起作用,因此不能使用MockitoRuleMockito运行器。


6
现在有一个官方的Mockito Junit5扩展程序,等效于MockitoJUnitRunner-> mockito-junit-jupiter
dan carter

当在的Mockito官方扩展发布后,写了一篇博客文章更多的细节如何配置和使用它:solidsoft.wordpress.com/2018/03/27/...
马辛Zajączkowski

注释方法@Test需要公开还是“私有包”足够好?
极客

使用Jupiter(通常称为“ JUnit 5”)运行测试时,测试方法只需要对程序包可见。
尼古拉

56

使用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

    ...
}

5
@ExtendWith(MockitoExtension.class)相当于@RunWith(MockitoJUnitRunner.class)JUnit4
Sergey Nemchinov,

9

有许多不同的方法可以做,但是更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-apimockito-junit-jupiter要看。


为什么不mockito-junit-jupiter拉正确版本的junit-jupiter-api
haelix

@haelix因为用于此依赖项的版本策略依赖于Mockito库。在这里查看版本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设计的。
davidxxx '18

MockitoExtensionmockito-core3.0.0版本中似乎不存在。
Thunderforge

1
@Thunderforge这是在mockito-junit-jupiter
davidxxx '19

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.