Springboot集成JUnit5优雅进行单元测试

简介: Springboot集成JUnit5优雅进行单元测试

单元测试在系统重构时能发挥巨大的做用,能够在重构后快速测试新的接口是否与重构前有出入


依赖

<!-- SpringBoot 2.4 以上版本移除了默认对 Vintage 的依赖。如果需要兼容junit4需要自行引入(不能使用junit4的功能 @Test)-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>
<!-- 兼容junit4需要自行引入vintage -->
<dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!--SpringBoot2.3.1-->
<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>
@SpringBootTest
class WebAdminApplicationTests {
    @Test
    void contextLoads() {
    }
}
  • junit5
import org.junit.jupiter.api.*;
import java.util.concurrent.TimeUnit;
@DisplayName("Junit5Test测试类")
public class Junit5Test {
    @DisplayName("测试displayname注解")
    @Test
    void testDisplayName(){
        System.out.println(1);
    }
    @BeforeEach
    void testBeforeEach() {
        System.out.println("测试就要开始了");
    }
    @AfterEach
    void testAfterEach() {
        System.out.println("测试就要结束了");
    }
    @Timeout(value=500, unit = TimeUnit.MILLISECONDS)
    @Test
    void testTimeout() throws InterruptedException {
        Thread.sleep(600);
    }
    @RepeatedTest(5)  // 重复执行5次
    @Test
    void testRepeatedTest() {
        System.out.println("1");
    }
}

注解


@BeforeEach:在每一个单元测试方法执行前都执行一遍

@BeforeAll:在每一个单元测试方法执行前执行一遍(只执行一次)

@DisplayName(“商品入库测试”):用于指定单元测试的名称

@Disabled:当前单元测试置为无效,即单元测试时跳过该测试

@RepeatedTest(n):重复性测试,即执行n次

@ParameterizedTest:参数化测试

@ValueSource(ints = {1, 2, 3}):参数化测试提供数据


断言


  • JUnit Jupiter提供了强大的断言方法用以验证结果,在使用时须要借助java8的新特性lambda表达式,均是来自org.junit.jupiter.api.Assertions包的static方法。code

assertTrue与assertFalse用来判断条件是否为true或false


  • assertTrue与assertFalse用来判断条件是否为true或false


@Test
@DisplayName("测试断言equals")
void testEquals() {
    assertTrue(3 < 4);
}

assertNull与assertNotNull用来判断条件是否为 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("调用");
}


7bbd4e46e8314ec6bdab37acb195cac7.png



参数化测试


参数化测试能够按照多个参数分别运行屡次单元测试这里有点相似于重复性测试,只不过每次运行传入的参数不用。须要使用到@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);
        }
    }
}


相关文章
|
2月前
|
IDE Java 测试技术
Junit 单元测试
JUnit是Java常用的单元测试框架,简化了测试用例的编写和执行。其特点包括简单注解、自动化测试、可扩展性、灵活性及与IDE的集成。使用方法涉及创建测试类、利用注解如@Test、@BeforeEach等管理测试生命周期,以及使用各种断言方法验证结果。此外,JUnit支持参数化测试以覆盖更多输入组合,并能与Maven、Gradle等构建工具集成,提升测试效率和项目管理。
42 1
|
4月前
|
Java 测试技术
JUnit 4 单元测试
单元测试是软件开发中必不可少的一环,但是在平常开发中往往因为项目周期紧,工作量大而被选择忽略,这样往往导致软件问题层出不穷。 线上出现的不少问题其实在有单元测试的情况下就可以及时发现和处理,因此培养自己在日常开发中写单元测试的能力是很有必要的。无论是对自己的编码能力的提高,还是项目质量的提升,都是大有好处,本文将介绍 Java 单元测试框架 JUnit 4 的基础认识和使用来编写单元测试,希望同样对你有所帮助。
|
6月前
|
Java 测试技术 数据库
Spring 单元测试(Junit)
Spring 单元测试(Junit)
|
5月前
|
测试技术
Junit单元测试 org.junit.jupiter.api.extension.ParameterResolutionException异常处理
Junit单元测试 org.junit.jupiter.api.extension.ParameterResolutionException异常处理
93 0
|
24天前
|
Java 测试技术 程序员
junit单元测试
junit单元测试
|
4月前
|
SQL Java 数据库连接
Mybatis之Mybatis简介、搭建Mybatis相关步骤(开发环境、maven、核心配置文件、mapper接口、映射文件、junit测试、log4j日志)
【1月更文挑战第2天】 MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code。随着开发团队转投Google Code旗下,iBatis3.x正式更名为MyBatis。代码于2013年11月迁移到Github iBatis一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBatis提供的持久层框架包括SQL Maps和Data Access Objects(DAO)
204 3
Mybatis之Mybatis简介、搭建Mybatis相关步骤(开发环境、maven、核心配置文件、mapper接口、映射文件、junit测试、log4j日志)
|
2月前
|
XML Java 测试技术
TestNG 与 JUnit 测试框架:哪个更好?
【2月更文挑战第16天】
49 1
TestNG 与 JUnit 测试框架:哪个更好?
|
3月前
|
运维 Java 测试技术
spring 单元测试 Junit
spring 单元测试 Junit
43 2
|
4月前
|
Java 测试技术 Spring
spring之单元测试:JUnit
【1月更文挑战第16天】 一、整合JUnit5 1、搭建子模块 2、引入依赖 3、添加配置文件 4、添加java类 5、测试 二、整合JUnit4 1、添加依赖 2、测试
76 4
|
4月前
|
Java 测试技术 C++
【JavaSE】Junit测试
【JavaSE】Junit测试
30 0