springboot单元测试

单元测试

junit4 与junit5的选择问题

1、问题描述
在使用SpringBoot2来进行单元测试时,发现不需要加@runWith注解,其次当测试类路径与boot启动类不是相同包或其子包时,必须指定启动类的 .clas

2、产生原因

  1. 首先针对这个问题,我们所使用的是springboot 2、值得注意的是这个版本对于junit做了较大的改动,移除了对junit3和4的支持,使用jupiter测试引擎替换了原来的junit4作为核心模块提供测试服务,这也是为什么昨天测试中最开始自动引入的是org.junit.jupiter的原因。
  2. 添加依赖spring_boot_starter_test后,可以在内部看到自带了jupiter测试核心模块,这是pom里最开始没有看到老版本junit4依赖的原因。

3、版本区别

-   junit4,也就是老版本在使用测试时,就需要像昨天后边一段一样,手动添加依赖支持,不过使用junit4需要使用@springbootTest和@runWith注解,其中runWith指向使用spring的测试模块。
    junit5(jupiter测试引擎)不再支持junit4(vintage测试引擎),在使用时自然不再需要spring来提供了,即不需要再使用@runWith注解。

-   最后一个小问题就是,@springbootTest属性的问题。分两种情况:
    1)测试类所在目录跟boot启动类目录相同或者是子目录的情况下,在测试时可以自动找到启动类。即注解中不需要指定启动类的字节码。
    2)不是相同目录或者子目录时,就需要指定启动类的字节码了.,@springbootTest(clases=✘✘✘.class)

4、ExtendWith(SpringExtension.class)、@DisplayName(“Base Test”)意义
Junit5:demo

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = Application.class)
@DisplayName("Base Test")
public class BaseTest {
    @Autowired
    protected WebApplicationContext wac;
    protected MockMvc               mockMvc;

    @org.junit.jupiter.api.BeforeEach
    public void setUp() throws Exception {
        mockMvc = webAppContextSetup(wac).build();
    }
}

Spring 2.4.0 的测试引擎 junit-vintage

从 Spring Boot 2.4.0 的测试引擎已经使用 Junit 5 的测试了。
因此测试引擎不再需要 exclude junit-vintage 到 Spring Boot 的测试依赖了。
2.4.0 的测试实例应该使用下面的依赖配置:

<!-- TESTS -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <scope>test</scope>
    </dependency>

###说明
单元测试 注入方法 @ExtendWith
当涉及Spring时:

如果您想在测试中使用Spring测试框架功能(例如)@MockBean,则必须使用@ExtendWith(SpringExtension.class)。它取代了不推荐使用的JUnit4@RunWith(SpringJUnit4ClassRunner.class)

当不涉及Spring时:

例如,如果您只想涉及Mockito而不必涉及Spring,那么当您只想使用@Mock/ @InjectMocks批注时,您就想使用@ExtendWith(MockitoExtension.class),因为它不会加载到很多不需要的Spring东西中。它替换了不推荐使用的JUnit4 @RunWith(MockitoJUnitRunner.class)。

要回答您的问题:

是的,您可以只使用@ExtendWith(SpringExtension.class),但是如果您的测试中没有涉及Spring测试框架功能,那么您可能只想使用@ExtendWith(MockitoExtension.class)

在升级

spring-boot-starter-parent版本到 2.4.0 以后JUnit 5 测试 Spring 引擎的时候提示 junit-vintage 错误

TestEngine with ID 'junit-vintage' failed to discover tests” with Spring

junit-vintage 是 Junit 4 中使用的引擎,如果你的项目使用了 Junit 5 的话,你需要在 spring-boot-starter-test 中将 JUnit 4 的引擎从测试中删除。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
    <exclusion>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
    </exclusion>
</exclusions>
</dependency>

Junit5生命周期注解 和 DisplayName 注解

  • Constructor:在 Juni5 中,每一个通过 @Test注解 调用的测试方法都是一个独立的实例,因此每一个测试方法都会调用构造函数:
  • @BeforeEach & @AfterEach 如注释的名称,在每一次 @Test 调用之前都会运行一次。
  • @BeforeAll 与 @AfterAll 会在所有测试执行之前执行,值得注意的是,@BeforeAll 与 @AfterAll 都是静态方法:
  • @DisplayName注解 用来提供个性化的名称,可以用于测试类与测试方法,用法大同小异。@DisplayName注解可以用来输出普通文字、特殊文字以及 emoji,能为测试提供更有意义的输出:
package com.example;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

@DisplayName("App Test with spaces")
public class AppTest
{
    @Test
    @DisplayName("中文对应")
    public void testOne()
    {
        System.out.println("testOne");
    }

    @Test
    @DisplayName("w(゚Д゚)w")
    public void testTwo()
    {
        System.out.println("testOne");
    }

    @Test
    @DisplayName("✔️")
    public void testThree()
    {
        System.out.println("testOne");
    }

    @Test
    @DisplayName("❌")
    public void testFour()
    {
        System.out.println("testOne");
    }
}

*:不同 编辑器/IDE 的配置不太一样,有的 IDE 可能不会显示原本的类/方法名,而是直接显示 @DisplayName 中的输入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值