Java 如何在 JUnit5 中使用 Mockito

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40961057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:01:53  来源:igfitidea点击:

How to use Mockito with JUnit5

javaunit-testingmockitojunit5

提问by Daniel K?fer

How can I use injection with Mockito and JUnit 5?

如何在 Mockito 和 JUnit 5 中使用注入?

In JUnit4 I can just use the @RunWith(MockitoJUnitRunner.class)Annotation. In JUnit5 is no @RunWithAnnotation?

在 JUnit4 中,我可以只使用@RunWith(MockitoJUnitRunner.class)注解。在JUnit5中是没有@RunWithAnnotation吗?

采纳答案by Nicolai

There are different ways to use Mockito - I'll go through them one by one.

Mockito 的使用方法有很多种——我会一一介绍。

Manually

手动

Creating mocks manually with Mockito::mockworks regardless of the JUnit version (or test framework for that matter).

Mockito::mock无论 JUnit 版本(或与此相关的测试框架)如何,都可以手动创建模拟。

Annotation Based

基于注释

Using the @Mock-annotation and the corresponding call to MockitoAnnotations::initMocksto create mocksworks regardless of the JUnit version (or test framework for that matter but Java 9 could interfere here, depending on whether the test code ends up in a module or not).

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

Mockito Extension

Mockito 扩展

JUnit 5 has a powerful extension modeland Mockito recently published one under the group / artifact ID org.mockito: mockito-junit-jupiter.

JUnit 5 有一个强大的扩展模型,Mockito 最近在 group/artifact ID org.mockito下发布了一个mockito-junit-jupiter

You can apply the extension by adding @ExtendWith(MockitoExtension.class)to the test class and annotating mocked fields with @Mock. From MockitoExtension's JavaDoc:

您可以通过添加@ExtendWith(MockitoExtension.class)到测试类并使用@Mock. 来自MockitoExtension的 JavaDoc:

@ExtendWith(MockitoExtension.class)
public class ExampleTest {

    @Mock
    private List list;

    @Test
    public void shouldDoSomething() {
        list.add(100);
    }

}

The MockitoExtension documentationdescribes other ways to instantiate mocks, for example with constructor injection (if you rpefer final fields in test classes).

MockitoExtension 文档描述了其他实例化模拟的方法,例如使用构造函数注入(如果您喜欢测试类中的最终字段)。

No Rules, No Runners

没有规则,没有跑步者

JUnit 4 rules and runners don't work in JUnit 5, so the MockitoRuleand the Mockito runnercan not be used.

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

回答by Daniel K?fer

You have to use the new @ExtendWithannotation.

您必须使用新@ExtendWith注释。

Unfortunately there is no extension yet release yet. On githubyou can see a beta implementation for the extension. as a example demo test.

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

回答by davidxxx

There are different ways to do but the cleaner way and that also respects the JUnit 5 philosophy is creating a org.junit.jupiter.api.extension.Extensionfor Mockito.

有不同的方法可以做,但更org.junit.jupiter.api.extension.Extension简洁的方法也尊重 JUnit 5 哲学是为 Mockito创建一个 。

1) Creating mocks manuallymakes lose the benefit of additional Mockito checks to ensure you use correctly the framework.

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

2) Calling MockitoAnnotations.initMocks(this)in every test classes is boiler plate code that we could avoid.
And making this setup in an abstract class is not a good solution either.
It couples every test classes to a base class.
If then you need a new base test class for good reasons, you finish with a 3- level class hierarchy. Please avoid that.

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

3) Test Rules is a JUnit 4 specificity.
Don't even think of that.
And the documentationis clear about that :

3) 测试规则是 JUnit 4 的特性。
甚至不要想那个。
文件对此也很清楚:

However, if you intend to develop a new extension for JUnit 5 please use the new extension model of JUnit Jupiter instead of the rule-based model of JUnit 4.

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

4) Test Runner is really not the way to extend the JUnit 5 framework.
JUnit 5 simplified the hell of the Runners of JUnit 4 by providing an extension model for writing tests thanks to JUnit 5 Extensions.
Don't even think of that.

4) Test Runner 真的不是扩展 JUnit 5 框架的方式。
由于 JUnit 5 扩展,JUnit 5 通过提供用于编写​​测试的扩展模型简化了 JUnit 4 的运行程序。
甚至不要想那个。

So favor the org.junit.jupiter.api.extension.Extensionway.

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



EDIT : Actually, Mockito bundles a jupiter extension : mockito-junit-jupiter

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

Then, very simple to use :

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

import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class FooTest {
     ...    
}

Here is an addition to the excellent answer of Jonathan.

这是乔纳森出色答案的补充。

By adding as dependency the mockito-junit-jupiterartifact, the use of @ExtendWith(MockitoExtension.class)produced the following exception as the test is executed :

通过将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;

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

THe problem is that mockito-junit-jupiterdepends on two independent libraries. For example for mockito-junit-jupiter:2.19.0:

问题在于这 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>

The problem was I used junit-jupiter-api:5.0.1.

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

So as junit-jupiter-apimoves still often in terms of API, make sure you depend on the same version of junit-jupiter-apithat mockito-junit-jupiterdepends on.

因此,由于junit-jupiter-apiAPI 方面的动作仍然经常发生,请确保您依赖的版本与junit-jupiter-apimockito-junit-jupiter依赖的版本相同。

回答by Jonathan

Use Mockito's MockitoExtension. The extension is contained in a new artifact mockito-junit-jupiter:

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

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>2.23.4</version>
    <scope>test</scope>
</dependency>

It allows you to write tests as you would have with JUnit 4:

它允许您像使用 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

    ...
}