跳至主要內容

spring-boot-starter-test

Jin...大约 5 分钟

spring-boot-starter-test

1、坐标

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

2、Junit5 简介

  • SpringBoot2.2.0开始引入Junit5作为单元测试默认库
  • Junit5和之前版本的Junit框架有很大不同,由三个不同子项目的几个不同模块组成
  • Junit5 = Junit Platform + Junit Jupiter + Junit Vintage
    • Junit Platform: 是在JVM上启动测试框架的基础,支持Junit自制的测试引擎,也可以接入其他引擎
    • JUnit Jupiter: Junit Jupiter提供Junit5新的编程模型,是JUnit5新特性的核心内部包含了一个测试引擎,用于在Junit Platform上运行
    • Junit Vintage: 为了兼容老项目,Junit vintage提供了兼容Junit4和Junit3的测试引擎

3、常用注解

注解含义
@Test表示方法是测试方法
@ParameterizedTest表示方法是参数化测试
@RepeatedTest表示方法可重复执行
@DisplayName为测试类或测试方法设置展示名称
@BeforeEach表示在每个单元测试之前执行
@AfterEach表示在每个单元测试后执行
@BeforeAll表示在所有单元测试之前执行
@AfterAll表示在所有单元测试之后执行
@Tag表示单元测试类别
@Disabled表示测试类或测试方法不执行
@Timeout表示测试方法运行如果超过指定时间会报错
@ExtendWith为测试类或测试方法提供扩展类引用

3.1、@DisplayName

@DisplayName("测试")
public class DisplayNameTest {

    @DisplayName("测试方法")
    @Test
    public void test() {
        System.out.println("测试方法");
    }
}
image-20240328155925379
image-20240328155925379

3.2、@BeforeEach和@AfterEach

public class BeforeAndAfterEachTest {
    @BeforeEach
    public void beforeEach() {
        System.out.println("beforeEach");
    }
    @AfterEach
    public void afterEach() {
        System.out.println("afterEach");
    }
    @Test
    public void test() {
        System.out.println("test");
    }
}

输出

beforeEach
test
afterEach

3.3、@BeforeAll和@AfterAll

测试@BeforeAll和@AfterAll,使用这两个注解的方法必须是静态方法:

public class BeforeAllAndAfterAllTest {

    @BeforeAll
    public static void beforeAll() {
        System.out.println("BeforeAllAndAfterAllTest.beforeAll");
    }

    @AfterAll
    public static void afterAll() {
        System.out.println("BeforeAllAndAfterAllTest.afterAll");
    }

    @Test
    public void test1() {
        System.out.println("BeforeAllAndAfterAllTest.test1");
    }
}

输出

BeforeAllAndAfterAllTest.beforeAll
BeforeAllAndAfterAllTest.test1
BeforeAllAndAfterAllTest.afterAll

4、断言

  • 断言(Assertions)是测试方法中的核心部分,用来对测试需要满足的条件进行验证
  • 这些断言方法都是org.junit.jupiter.api.Assertions的静态方法
  • 用来检查业务逻辑返回的数据是否合理,所有测试结束后,会有一个详细报告
  • 同一个方法内前面的断言失败则后续代码不执行
方法含义
assertEquals判断两个对象或两个原始类型是否相等
assertNotEquals判断两个对象或两个原始类型是否不相等
assertSame判断两个对象引用是否指向同一个对象
assertNotSame判断两个对象引用是否指向不同对象
assertTrue判断得到的布尔值是否为真
assertFalse判断得到的布尔值是否为假
assertNull判断给定的对象引用是否为null
assertNotNull判断给定的对象引用是不是null

4.1、简单断言

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

@DisplayName("断言测试")
public class AssertionsTest {

    int cal(int i, int y) {
        return i + y;
    }

    @Test
    void test() {
        int val = cal(1, 1);
        Assertions.assertEquals(5, val);
    }
}

输出

image-20240328161250343
image-20240328161250343

4.2、组合断言

断言机制还提供组合断言,即通过assertAll判断所有断言,通过Lambda表达式写出多条断言,全部成功则断言成功,有一个失败此断言失败:

    @Test
    @DisplayName("组合断言")
    void test1() {
        Assertions.assertAll("Jin",
                () -> Assertions.assertEquals(1, cal(1, 1)),
                () -> Assertions.assertEquals(1, cal(1, 2))
        );
    }

输出

org.opentest4j.AssertionFailedError: 
预期:1
实际:2

4.3、异常断言

	@Test
    @DisplayName("异常断言")
    void test2() {
        Assertions.assertThrowsExactly(RuntimeException.class, () -> Assertions.assertEquals(1, cal(1, 1)));
    }

输出

org.opentest4j.AssertionFailedError: Unexpected exception type thrown, 
预期:class java.lang.RuntimeException
实际:class org.opentest4j.AssertionFailedError

4.4、快速失败

fail方法快速失败,即遇到某种条件时终止测试

    @Test
    @DisplayName("快速失败")
    void testAssert() {
        if(cal(1, 3) != 5) {
            Assertions.fail("cal方法有误");
        }
    }

输出

org.opentest4j.AssertionFailedError: cal方法有误

5、前置条件

JUnit5 中的前置条件 Assumptions 类似断言,但不同之处在于不满足断言会使得测试方法失败,而不满足前置条件会使得测试方法执行终止,前置条件可以看做执行测试方法的前提,当前提不满足就没必要继续执行

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

@DisplayName("前置条件Assumptions")
public class AssumptionsTest {
    int cal(int i, int y) {
        return i + y;
    }

    @Test
    @DisplayName("前置条件")
    public void testAssumptions() {
        Assumptions.assumeTrue(cal(1, 2) == 3);
        System.out.println("执行正常");
    }
}

输出

执行正常

6、参数化测试

参数化测试是 JUnit5 的一个新特性,它使得用不同的参数多次运行测试成为可能,利用 @ValueSource 等注解,指定入参,可以使用不同参数进行多次单元测试,而不需要每新增一个参数就新增一个单元测试,省去了很多冗余代码

注解含义
@ValueSource为参数化测试指定入参来源,支持八大基础类型以及String、Class类型
@NullSource为参数化测试提供一个null作为入参
@EnumSource为参数化测试提供一个枚举的入参
@CsvFileSource表示读取Csv文件内容作为参数化测试入参
@MethodSource表示读取方法的返回值作为参数化测试入参

参数化测试使用

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

@DisplayName("参数化测试")
public class ParameterTest {
    @ParameterizedTest
    @DisplayName("参数化测试")
    @ValueSource(ints = {1, 2, 3, 4})
    public void test(int i) {
        System.out.println(i);
    }
}

方法的返回值作为入参

使用某个方法的返回值作为入参,提供参数的方法必须是静态的且返回Stream:

    static Stream<String> meth() {
        return Stream.of("Jin", "JinX");
    }

    @ParameterizedTest
    @DisplayName("方法的返回值作为入参")
    @MethodSource(value = "meth")
    public void test1(String str) {
        System.out.println(str);
    }

输出

Jin
JinX
贡献者: Jin
你认为这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度