如何在 JUnit5 中使用 Mockito

     2023-02-15     251

关键词:

【中文标题】如何在 JUnit5 中使用 Mockito【英文标题】:How to use Mockito with JUnit5 【发布时间】:2017-04-19 01:36:39 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

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

手动

使用Mockito::mock 手动创建模拟无论 JUnit 版本(或测试框架)如何。

基于注释

使用@Mock-注解和对MockitoAnnotations::initMocks的相应调用 到create mocks 的工作原理与 JUnit 版本无关(或测试框架,但 Java 9 可能会在此处干扰,具体取决于测试代码是否最终在模块中)。

Mockito 扩展

JUnit 5 有 a powerful extension model 和 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);
    


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

没有规则,没有跑步者

JUnit 4 规则和运行器在 JUnit 5 中不起作用,因此无法使用 MockitoRule 和 Mockito runner。

【讨论】:

现在有一个官方的 Mockito Junit5 扩展,相当于 MockitoJUnitRunner -> mockito-junit-jupiter Mockito 官方扩展发布时,写了一篇博文,详细介绍了如何配置和使用它:solidsoft.wordpress.com/2018/03/27/… 注解@Test的方法是否需要公开或者“包私有”是否足够好? 使用 Jupiter(通常称为“JUnit 5”)运行测试时,测试方法只需要包可见。 回到这一点 - 有没有首选的方法?有什么建议吗?还是基于意见?【参考方案2】:

使用 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) 相当于 JUnit4 的 @RunWith(MockitoJUnitRunner.class) 我可以使用 JUnit5 中的 MockitoExtension.class 对 Mock 对象的方法执行具有不同返回值的方法的多次调用 @RajHassani 是的,您可以,请参阅here。【参考方案3】:

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

1) Creating mocks manually 失去了额外的 Mockito 检查的好处,以确保您正确使用框架。

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

3) 测试规则是 JUnit 4 的特殊性。 想都别想。documentation 很清楚这一点:

但是,如果您打算为 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 方面仍然经常移动,请确保您依赖于 mockito-junit-jupiter 所依赖的同一版本的 junit-jupiter-api

【讨论】:

为什么mockito-junit-jupiter 不提取正确版本的junit-jupiter-api @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 设计的。 MockitoExtensionmockito-core 版本 3.0.0 中似乎不存在。 @Thunderforge 这在mockito-junit-jupiter中定义【参考方案4】:

你必须使用新的@ExtendWith注解。

很遗憾,还没有发布任何扩展。 在github 上,您可以看到扩展的测试版实现。以demo test为例。

【讨论】:

单元测试实践(springcloud+junit5+mockito+datamocker)

网上看过一句话,单元测试就像早睡早起,每个人都说好,但是很少有人做到。从这么多年的项目经历亲身证明,是真的。这次借着项目内实施单元测试的机会,记录实施的过程和一些总结经验。项目情况首先是背景,项目是一... 查看详情

如何使用 Mockito 在 Spring 中模拟自动装配的 @Value 字段?

】如何使用Mockito在Spring中模拟自动装配的@Value字段?【英文标题】:HowdoImockanautowired@ValuefieldinSpringwithMockito?【发布时间】:2014-06-0311:22:51【问题描述】:我正在使用Spring3.1.4.RELEASE和Mockito1.9.5。在我的春季课程中,我有:@Value("#... 查看详情

如何使用 Mockito 在单元测试中调用 AppCompatActivity onCreate

】如何使用Mockito在单元测试中调用AppCompatActivityonCreate【英文标题】:HowtocallAppCompatActivityonCreateinunittestusingMockito【发布时间】:2018-07-0408:22:44【问题描述】:我想为AndroidActivity类编写一个简单的单元测试。扩展Activity时测试运行... 查看详情

如何使用 Mockito 在 Flutter 中正确模拟 NavigatorObserver?

】如何使用Mockito在Flutter中正确模拟NavigatorObserver?【英文标题】:HowtocorrectlymockNavigatorObserverinFlutterwithMockito?【发布时间】:2020-04-2502:51:09【问题描述】:我有一个测试,当应用程序从contacts_footer.dart导航到create_and_edit_contact.dart... 查看详情

如何使用 Mockito 和 JUnit 在 Spring Boot 中测试 POST 方法

】如何使用Mockito和JUnit在SpringBoot中测试POST方法【英文标题】:HowtotestPOSTmethodinSpringbootusingMockitoandJUnit【发布时间】:2018-12-2302:43:11【问题描述】:我是在SpringBoot框架中使用JUnit和Mockito进行单元测试的新手。我想测试这个方法。... 查看详情

如何在 Java 中使用 Mockito 模拟结果集并填充它

】如何在Java中使用Mockito模拟结果集并填充它【英文标题】:howtomockresultsetandpopulateitusingMockitoinJava【发布时间】:2011-09-1004:14:52【问题描述】:我有用CallableStatement.executeQuery()填充Resultset的代码。我嘲笑了ResultSet和CallableStatement... 查看详情

如何在 Mockito 中模拟全局变量

】如何在Mockito中模拟全局变量【英文标题】:howtomockglobalvariableinMockito【发布时间】:2016-04-2611:22:49【问题描述】:我有一个全局变量global。我的方法有一行:global.getListOfObjects()我正在尝试编写单元测试并在上述行中不断获得NP... 查看详情

junit5eclipsejava测试

我正在使用Mockito进行JUnit5测试,这里是完整的代码,请看看,让我知道如何解决这个问题:packagehotel.entities;importstaticorg.junit.jupiter.api.Assertions.*;importorg.junit.jupiter.api.AfterEach;importorg.junit.jupiter.api.BeforeEach;impor 查看详情

如何在多模块项目中使用 JUnit5 和 SpringBoot2 通过 gradle 而不是 intelliJ 运行测试

】如何在多模块项目中使用JUnit5和SpringBoot2通过gradle而不是intelliJ运行测试【英文标题】:HowtoruntestsbygradleinsteadofintelliJwithJUnit5andSpringBoot2inmultimoduleproject【发布时间】:2020-01-2918:39:26【问题描述】:我创建了一个空的gradle项目,... 查看详情

如何在 JUnit Test Java 中替换 Mockito 以存根类

】如何在JUnitTestJava中替换Mockito以存根类【英文标题】:HowtosubstituteMockitoinplacetostubaclassinJUnitTestJava【发布时间】:2018-06-2205:10:01【问题描述】:我试图在JUnit的测试会话期间替换Mockito的正确使用来代替存根类。不幸的是,网上... 查看详情

重学springboot系列之mockito测试(代码片段)

重学SpringBoot系列之Mockito测试mock中文文档使用Mockito编码完成接口测试编码实现接口测试为什么要写代码做测试?使用接口测试工具Postman很方便啊junit测试框架Mockito测试框架真实servlet容器环境下的测试@SpringBootTest注解@E... 查看详情

如何在 JUnit 5 中使用 @RestTemplateClient?

】如何在JUnit5中使用@RestTemplateClient?【英文标题】:Howtouse@RestTemplateClientwithJUnit5?【发布时间】:2019-12-2314:51:10【问题描述】:我使用springboot2.1.7.RELEASE和junit5。不幸的是,@RestClientTest有问题,因为我收到java.lang.IllegalStateException... 查看详情

执行 Mockito 时抛出空指针异常

】执行Mockito时抛出空指针异常【英文标题】:NullPointerExceptionthrownwhenMockitoisexecuted【发布时间】:2020-03-1320:32:25【问题描述】:以下代码在执行时会在该步骤抛出空指针异常:this.mockMvc.perform【问题讨论】:【参考方案1】:如果... 查看详情

如何使用 mockito 模拟方法?

】如何使用mockito模拟方法?【英文标题】:Howtomockmethodsusingmockito?【发布时间】:2020-12-0814:10:53【问题描述】:我有一个抽象类和一个派生类。派生类是一个服务,因此会自动装配到测试类中。我需要模拟和测试抽象类中有一个... 查看详情

在maven项目中运行junit5测试用例

本文演示了如何如何编写JUnit5测试用例,在Maven项目中运行JUnit5测试用例。编写JUnit5测试用例如果你是Java开发者,那么对于JUnit应该就不陌生。JUnit是Java单元测试的基础工具。JUnit目前最新的版本是JUnit5.x,但广大的Java开发者估... 查看详情

junit5如何使用guicedi(代码片段)

Guice是一个依赖注入的小清新工具。相比Spring的依赖管理来说,这个工具更加小巧,我们可以在测试中直接使用。Junit5在Junit中使用就没有那么方便了,因为Junit没有Guice的注解。你需要手动写一个类,在这个类中,对Injector的模... 查看详情

如何使用mockito正确模拟每个循环?(代码片段)

我想测试我的方法,我需要模拟项目和行的向量来完成每个方法。当我从Item类(在测试中)调用getRows()时,我准备了我想要得到的结果向量。问题是测试中getRows方法的结果总是为空,因此这意味着doReturn语句在这里无法正常... 查看详情

如何使用 SpringBoot2、JUnit5 和 Kotlin 将配置属性注入单元测试

】如何使用SpringBoot2、JUnit5和Kotlin将配置属性注入单元测试【英文标题】:HowcanIinjectconfigpropertiesintoaunittest,usingSpringBoot2,JUnit5,andKotlin【发布时间】:2018-12-2202:03:35【问题描述】:我的场景:我正在构建一个使用Kotlin和SpringBoot2.0.3... 查看详情