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);
        }
    }
}


相关文章
|
4月前
|
XML Java 测试技术
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
这篇文章介绍了Spring5框架的三个新特性:支持@Nullable注解以明确方法返回、参数和属性值可以为空;引入函数式风格的GenericApplicationContext进行对象注册和管理;以及如何整合JUnit5进行单元测试,同时讨论了JUnit4与JUnit5的整合方法,并提出了关于配置文件加载的疑问。
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
|
2月前
|
Java 程序员 测试技术
Java|让 JUnit4 测试类自动注入 logger 和被测 Service
本文介绍如何通过自定义 IDEA 的 JUnit4 Test Class 模板,实现生成测试类时自动注入 logger 和被测 Service。
26 5
|
3月前
|
SQL JavaScript 前端开发
基于Java访问Hive的JUnit5测试代码实现
根据《用Java、Python来开发Hive应用》一文,建立了使用Java、来开发Hive应用的方法,产生的代码如下
74 6
|
4月前
|
测试技术
单元测试问题之使用TestMe时利用JUnit 5的参数化测试特性如何解决
单元测试问题之使用TestMe时利用JUnit 5的参数化测试特性如何解决
49 2
|
4月前
|
Java 测试技术 Maven
单元测试问题之在Maven项目中引入JUnit 5和Mockito的依赖如何解决
单元测试问题之在Maven项目中引入JUnit 5和Mockito的依赖如何解决
214 1
|
4月前
|
测试技术
如何使用 JUnit 测试方法是否存在异常
【8月更文挑战第22天】
72 0
|
4月前
|
Java 测试技术 Maven
Junit单元测试 @Test的使用教程
这篇文章是一个关于Junit单元测试中`@Test`注解使用的教程,包括在Maven项目中添加Junit依赖、编写带有@Test注解的测试方法,以及解决@Test注解不生效的常见问题。
|
4月前
|
前端开发 Java 测试技术
单元测试问题之在Spring MVC项目中添加JUnit的Maven依赖,如何操作
单元测试问题之在Spring MVC项目中添加JUnit的Maven依赖,如何操作
|
6月前
|
运维 Java 测试技术
Spring运维之boo项目表现层测试加载测试的专用配置属性以及在JUnit中启动web服务器发送虚拟请求
Spring运维之boo项目表现层测试加载测试的专用配置属性以及在JUnit中启动web服务器发送虚拟请求
48 3
|
6月前
|
Java Maven Spring
spring如何使用junit进行测试
spring如何使用junit进行测试
spring如何使用junit进行测试