SpringBoot单元测试-JUnit5(嵌套测试、参数测试)

发布时间:2024年01月08日

1. 整合

SpringBoot提供一系列测试工具集及注解方便我们进行测试

spring-boot-test-autoconfigure提供测试的一些自动配置,spring-boot-test提供核心测试能力,只需要导入spring-boot-starter-test即可整合测试

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

spring-boot-starter-test默认提供了以下库供我们测试使用

  • JUnit 5
  • Spring Test
  • AssertJ
  • Hamcrest
  • Mockito
  • JSONassert
  • JsonPath

2. 测试

直接@Autowired容器中的组件进行测试

2.1 基本测试

JUnit5的注解与JUnit4的注解有所变化。常用的测试注解如下:

  • @Test :表示方法是测试方法。但是与JUnit4的@Test不同,他的职责非常单一不能声明任何属性,拓展的测试将会由Jupiter提供额外测试
  • @ParameterizedTest :表示方法是参数化测试。后面会详细介绍
  • @RepeatedTest :表示方法可重复执行
  • @DisplayName :为测试类或者测试方法设置展示名称
  • @BeforeEach :表示在每个单元测试之前执行。可能执行多次
  • @AfterEach :表示在每个单元测试之后执行。可能执行多次
  • @BeforeAll :表示在所有单元测试之前执行。只执行一次
  • @AfterAll :表示在所有单元测试之后执行。只执行一次
  • @Tag :表示单元测试类别,类似于JUnit4中的@Categories
  • @Disabled :表示测试类或测试方法不执行,类似于JUnit4中的@Ignore。但还是可以手动单独执行@Disabled注解的测试类或测试方法
  • @Timeout :表示测试方法运行如果超过了指定时间将会返回错误
  • @ExtendWith :为测试类或测试方法提供扩展类引用

常用断言如下:

  • assertEquals:判断两个对象或两个原始类型是否相等
  • assertNotEquals:判断两个对象或两个原始类型是否不相等
  • assertSame:判断两个对象引用是否指向同一个对象
  • assertNotSame:判断两个对象引用是否指向不同的对象
  • assertTrue:判断给定的布尔值是否为true
  • assertFalse:判断给定的布尔值是否为false
  • assertNull:判断给定的对象引用是否为null
  • assertNotNull:判断给定的对象引用是否不为null
  • assertArrayEquals:数组断言
  • assertAll:组合断言
        Assertions.assertAll("valueTest",
                () -> Assertions.assertTrue(true),
                () -> Assertions.assertFalse(false)
        );
  • assertThrows:异常断言
  • assertTimeout:超时断言
        Assertions.assertTimeout(Duration.ofMillis(2L), () -> {
            Thread.sleep(1L);
        });
  • fail:快速失败

使用示例:

package com.hh.springboot3test;


import org.junit.jupiter.api.*;
import org.springframework.boot.test.context.SpringBootTest;


// 具备测试SpringBoot容器中所有组件的功能
@SpringBootTest
// 测试类必须在主程序所在的包及其子包
class SpringBoot3TestApplicationTests {

    @BeforeAll
    static void initOne() {
        System.out.println("init one");
    }

    @BeforeEach
    void initEach() {
        System.out.println("init each");
    }


    @DisplayName("😱")
    @Test
    void contextLoads() {
        Integer calValue = 3;
        Assertions.assertEquals(3, calValue);

        Assertions.assertThrows(Exception.class, () -> {
            Integer.parseInt("One");
        });
    }


}

2.2 复杂测试

2.2.1 嵌套测试

JUnit 5可以通过Java中的内部类和@Nested注解实现嵌套测试,从而可以更好的把相关的测试方法组织在一起。在内部类中可以使用@BeforeEach和@AfterEach注解,而且嵌套的层数没有限制

使用示例:

package com.hh.springboot3test;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.springframework.boot.test.context.SpringBootTest;


@SpringBootTest
public class NestTest {

    @Nested
    @DisplayName("nest test 1")
    class NestTest1 {

        @BeforeAll
        static void nestTest1InitOne() {
            System.out.println("nest test 1 init one");
        }

        @Nested
        class NestTest2 {

        }
    }
}

2.2.2 参数化测试

参数化测试是JUnit5很重要的一个新特性,它使得用不同的参数多次运行测试成为了可能,也为我们的单元测试带来许多便利

利用@ValueSource等注解,指定入参,我们将可以使用不同的参数进行多次单元测试,而不需要每新增一个参数就新增一个单元测试,省去了很多冗余代码。常用参数注解如下:

  • @ValueSource: 为参数化测试指定入参来源,支持八大基础类型以及String类型、Class类型。使用示例:
    @ParameterizedTest
    @ValueSource(strings = {"one", "two", "three"})    // initEach也会执行3次
    public void parameterizedValueSourceTest(String str) {
        System.out.println(str);
        Assertions.assertTrue(StringUtils.isNotBlank(str));
    }

  • @NullSource: 表示为参数化测试提供一个null的入参
  • @EnumSource: 表示为参数化测试提供一个枚举入参
  • @CsvFileSource:表示读取指定CSV文件内容作为参数化测试入参
  • @MethodSource:表示读取指定方法的返回值作为参数化测试入参(注意方法返回需要是一个流)
    @ParameterizedTest
    @MethodSource("fruitMethod")    //指定方法名, 方法返回值就是测试用的参数
    public void parameterizedMethodSourceTest(String str) {
        System.out.println(str);
        Assertions.assertNotNull(str);
    }

    static Stream<String> fruitMethod() {
        return Stream.of("apple", "banana");
    }
文章来源:https://blog.csdn.net/yy8623977/article/details/131896697
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。