掘金 后端 ( ) • 2024-04-28 11:15

🙏废话不多说系列,直接开整🙏

女18.jpg

一、常用注解

  • @BeforeEach:在每个单元测试方法执行前都执行一遍
  • @BeforeAll:在每个单元测试方法执行前执行一遍(只执行一次)
  • @DisplayName("商品入库测试"):用于指定单元测试的名称
  • @Disabled:当前单元测试置为无效,即单元测试时跳过该测试
  • @RepeatedTest(n):重复性测试,即执行n次
  • @ParameterizedTest:参数化测试,
  • @ValueSource(ints = {1, 2, 3}):参数化测试提供数据

二、引入依赖使用

spring-boot 2.4.3

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

(1)重复测试

@RepeatedTest(value = 4)
@DisplayName("重复测试")
void repeatedTest(){
    System.out.println("重复测试");
}

结果展示:

image.png

(2)参数化测试

@ParameterizedTest
@ValueSource(ints = {1, 2, 3})
@DisplayName("参数化测试")
void paramTest(int a) {
    assert(a > 0 && a < 4);
}

image.png

(3)内嵌测试

junit5 提供了嵌套单元测试的功能,可以更好的展示测试类之间的业务逻辑关系,我们通常是一个业务对应一个测试类,有业务关系的类其实可以写在一起。这样有利于进行测试。而且内联的写法可以大大减少不必要的类,精简项目,防止类爆炸等一系列问题。

@SpringBootTest
@AutoConfigureMockMvc
@DisplayName("Junit5单元测试")
public class MockTest {
    //....
    @Nested
    @DisplayName("内嵌订单测试")
    class OrderTestClas {
        @Test
        @DisplayName("取消订单")
        void cancelOrder() {
            int status = -1;
            System.out.println("取消订单成功,订单状态为:"+status);
        }
    }
}

image.png

#### (4)断言测试示例
    // assertNull与assertNotNull用来判断条件是否为·null
    @Test
    @DisplayName("测试断言 NotNull")
    void testNotNull() {
        Assertions.assertNotNull(new Object());
    }

    // assertThrows用来判断执行抛出的异常是否符合预期,并可以使用异常类型接收返回值进行其他操作
    @Test
    @DisplayName("测试断言 抛出异常")
    void testThrow() {
        ArithmeticException arithmeticException = Assertions.assertThrows(ArithmeticException.class, () -> {
            int n = 5 / 0;
        });
        Assertions.assertEquals("/ by zero", arithmeticException.getMessage());
    }

    @Test
    @DisplayName("测试断言 超时")
        // assertTimeout用来判断执行过程是否超时
    void testTimeout() {
        String actualResult = Assertions.assertTimeout(Duration.ofSeconds(2), () -> {
            Thread.sleep(1000);
            return "a result";
        });
        System.out.println(actualResult);
    }


    @Test
    @DisplayName("测试组合断言")
        // assertAll是组合断言,当它内部所有断言正确执行完才算通过
    void testAll() {
        Assertions.assertAll("测试 item 商品下单",
                () -> {
                    //模拟用户余额扣减
                    Assertions.assertTrue(1 < 2, "余额不足");
                },
                () -> {
                    //模拟item数据库扣减库存
                    Assertions.assertTrue(3 < 4);
                },
                () -> {
                    //模拟交易流水落库
                    Assertions.assertNotNull(new Object());
                }
        );
    }

最后,全部示例

献上本人全部的测试用例

package edu.study.module.up;

import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.Duration;

@SpringBootTest
class DemoApplicationTests {

    @Test
    void contextLoads() {
    }

    @BeforeAll  // 在执行这个测试类(即以下执行所有测试方法时,才会执行此方法,此方法为 static 静态方法)
    static void testBeforeAll(){
        System.out.println("test  before All.");
    }

    @BeforeEach // 在每次执行单独的一个测试方法时,都会先执行此方法
    void testBeforeEach(){
        System.out.println("test  before each.");
    }

    @Disabled
    @DisplayName("当前单元测试置为无效,即单元测试时跳过该测试")
    @Test
    void testDisabled(){
        System.out.println("此方法在执行时,不会输出");
    }

    // assertNull与assertNotNull用来判断条件是否为·null
    @Test
    @DisplayName("测试断言 NotNull")
    void testNotNull() {
        Assertions.assertNotNull(new Object());
    }

    // assertThrows用来判断执行抛出的异常是否符合预期,并可以使用异常类型接收返回值进行其他操作
    @Test
    @DisplayName("测试断言 抛出异常")
    void testThrow() {
        ArithmeticException arithmeticException = Assertions.assertThrows(ArithmeticException.class, () -> {
            int n = 5 / 0;
        });
        Assertions.assertEquals("/ by zero", arithmeticException.getMessage());
    }

    @Test
    @DisplayName("测试断言 超时")
        // assertTimeout用来判断执行过程是否超时
    void testTimeout() {
        String actualResult = Assertions.assertTimeout(Duration.ofSeconds(2), () -> {
            Thread.sleep(1000);
            return "a result";
        });
        System.out.println(actualResult);
    }


    @Test
    @DisplayName("测试组合断言")
        // assertAll是组合断言,当它内部所有断言正确执行完才算通过
    void testAll() {
        Assertions.assertAll("测试 item 商品下单",
                () -> {
                    //模拟用户余额扣减
                    Assertions.assertTrue(1 < 2, "余额不足");
                },
                () -> {
                    //模拟item数据库扣减库存
                    Assertions.assertTrue(3 < 4);
                },
                () -> {
                    //模拟交易流水落库
                    Assertions.assertNotNull(new Object());
                }
        );
    }

    @RepeatedTest(value = 4)
    @DisplayName("重复测试")
    void repeatedTest() {
        System.out.println("重复测试");
    }


    @ParameterizedTest
    @ValueSource(ints = {1, 2, 3})
    @DisplayName("参数化测试")
    void paramTest(int a) {
        assert (a > 0 && a < 4);
    }

    @Nested
    @DisplayName("内嵌订单测试")
    class OrderTestClas {
        @Test
        @DisplayName("取消订单")
        void cancelOrder() {
            int status = -1;
            System.out.println("取消订单成功,订单状态为:" + status);
        }

        @RepeatedTest(3)
        @DisplayName("取消订单")
        void cancelOrder2() {
            int status = -1;
            System.out.println("取消订单成功,订单状态为:" + status);
        }
    }

}

结果展示

image.png


🙏至此,非常感谢阅读🙏

cat009.png