关于java:Spring-Boot-集成-JUnit5优雅单元测试

作者:海向\
起源:www.cnblogs.com/haixiang/p/13812363.html

为什么应用JUnit5

  • JUnit4被宽泛应用,然而许多场景下应用起来语法较为繁琐,JUnit5中反对lambda表达式,语法简略且代码不冗余。
  • JUnit5易扩大,包容性强,能够接入其余的测试引擎。
  • 性能更弱小提供了新的断言机制、参数化测试、重复性测试等新性能。
  • ps:开发人员为什么还要测试,单测写这么标准有必要吗?其实单测是开发人员必备技能,只不过很多开发人员开发工作太重导致调试完就不论了,没有系统化得单元测试,单元测试在零碎重构时能施展微小的作用,能够在重构后疾速测试新的接口是否与重构前有出入。

简介

如图,JUnit5构造如下:

  • JUnit Platform: 这是Junit提供的平台功能模块,通过它,其它的测试引擎都能够接入Junit实现接口和执行。
  • JUnit JUpiter:这是JUnit5的外围,是一个基于JUnit Platform的引擎实现,它蕴含许多丰盛的新个性来使得自动化测试更加不便和弱小。
  • JUnit Vintage:这个模块是兼容JUnit3、JUnit4版本的测试引擎,使得旧版本的自动化测试也能够在JUnit5下失常运行。

依赖引入

咱们以SpringBoot2.3.1为例,引入如下依赖,避免应用旧的junit4相干接口咱们将其依赖排除。

<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>

罕用注解

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

断言

JUnit Jupiter提供了弱小的断言办法用以验证后果,在应用时须要借助java8的新个性lambda表达式,均是来自org.junit.jupiter.api.Assertions包的static办法。

assertTrue`与`assertFalse`用来判断条件是否为`true`或`false
@Test
@DisplayName("测试断言equals")
void testEquals() {
    assertTrue(3 < 4);
}

assertNullassertNotNull用来判断条件是否为·null

@Test
@DisplayName("测试断言NotNull")
void testNotNull() {
    assertNotNull(new Object());
}

assertThrows用来判断执行抛出的异样是否合乎预期,并能够应用异样类型接管返回值进行其余操作

@Test
@DisplayName("测试断言抛异样")
void testThrows() {
    ArithmeticException arithExcep = assertThrows(ArithmeticException.class, () -> {
        int m = 5/0;
    });
    assertEquals("/ by zero", arithExcep.getMessage());
}

assertTimeout用来判断执行过程是否超时

@Test
@DisplayName("测试断言超时")
void testTimeOut() {
    String actualResult = assertTimeout(ofSeconds(2), () -> {
        Thread.sleep(1000);
        return "a result";
    });
    System.out.println(actualResult);
}

assertAll是组合断言,当它外部所有断言正确执行完才算通过

@Test
@DisplayName("测试组合断言")
void testAll() {
    assertAll("测试item商品下单",
              () -> {
                  //模仿用户余额扣减
                  assertTrue(1 < 2, "余额有余");
              },
              () -> {
                  //模仿item数据库扣减库存
                  assertTrue(3 < 4);
              },
              () -> {
                  //模仿交易流水落库
                  assertNotNull(new Object());
              }
             );
}

重复性测试

在许多场景中咱们须要对同一个接口办法进行反复测试,例如对幂等性接口的测试。

JUnit Jupiter通过应用@RepeatedTest(n)指定须要反复的次数

@RepeatedTest(3)
@DisplayName("反复测试")
void repeatedTest() {
    System.out.println("调用");
}

参数化测试

参数化测试能够依照多个参数别离运行屡次单元测试这里有点相似于重复性测试,只不过每次运行传入的参数不必。须要应用到@ParameterizedTest,同时也须要@ValueSource提供一组数据,它反对八种根本类型以及String和自定义对象类型,应用极其不便。

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

内嵌测试

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

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

近期热文举荐:

1.Java 15 正式公布, 14 个新个性,刷新你的认知!!

2.终于靠开源我的项目弄到 IntelliJ IDEA 激活码了,真香!

3.我用 Java 8 写了一段逻辑,共事直呼看不懂,你试试看。。

4.吊打 Tomcat ,Undertow 性能很炸!!

5.《Java开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞+转发哦!

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理