如何在JUnit 5中使用Mockito?

wmtdaxz3  于 9个月前  发布在  其他
关注(0)|答案(5)|浏览(74)

如何在Mockito和JUnit 5中使用注入?
在JUnit 4中,我可以只使用@RunWith(MockitoJUnitRunner.class)注解。
在JUnit 5中,没有@RunWith注解。

wfveoks0

wfveoks01#

使用Mockito有不同的方法-我将逐一介绍。

手动

使用Mockito::mock手动创建mock可以工作,而不管JUnit版本如何(或测试框架如何)。

基于标注

使用@Mock-annotation和对MockitoAnnotations::initMocks的相应调用来创建mocks可以工作,而不管JUnit版本如何(或者测试框架,但Java 9可能会干扰这里,这取决于测试代码是否最终在模块中)。

Mockito扩展

JUnit 5有a powerful extension model和Mockito最近在group / artifact 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);
    }

}

The MockitoExtension documentation描述了示例化mock的其他方法,例如使用构造函数注入(如果您在测试类中rpefer final字段)。

没有规则,没有跑步者

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

vi4fp9gy

vi4fp9gy2#

使用Mockito的MockitoExtension。该扩展包含在新工件mockito-junit-jupiter中:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>4.5.1</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

    ...
}
baubqpgj

baubqpgj3#

有不同的方法,但更干净的方法,也尊重JUnit 5的哲学是为Mockito创建一个org.junit.jupiter.api.extension.Extension
1)Creating mocks manually使您失去了额外的Mockito检查的好处,以确保您正确使用框架。
2)在每个测试类中调用MockitoAnnotations.initMocks(this)是我们可以避免的样板代码。
在抽象类中进行这种设置也不是一个好的解决方案。
它将每个测试类耦合到一个基类。
如果您有充分的理由需要一个新的基本测试类,那么您可以完成一个3级类层次结构。请避免这种情况。
3)测试规则是JUnit 4的特性。
想都别想
文件对此很清楚:
但是,如果您打算为JUnit 5开发新的扩展,请使用JUnit Jupiter的新扩展模型,而不是JUnit 4的基于规则的模型。
4)TestRunner真的不是扩展JUnit 5框架的方法。
由于JUnit 5扩展,JUnit 5通过提供用于编写测试的扩展模型简化了JUnit 4的运行者地狱。
想都别想
所以支持org.junit.jupiter.api.extension.Extension方式。
编辑:实际上,Mockito捆绑了一个jupiter扩展: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方面仍然经常移动,因此请确保您依赖于mockito-junit-jupiter所依赖的junit-jupiter-api的同一版本。

mitkmikd

mitkmikd4#

您必须使用新的@ExtendWith注解。
不幸的是,还没有发布扩展。在github上,您可以看到该扩展的beta实现。例如demo test

kx1ctssn

kx1ctssn5#

对于Kotlin,在注解字段时,请确保标记为lateinit

@ExtendWith(MockitoExtension.class)
class MyTest {
    @Mock
    lateinit var list: List

    @Test
    fun `Test should work`() {
        list.add(100)
    }
}

相关问题