• 单元测试JUnit5上手


    1. JUnit5的架构

    JUnit 5 与以前版本的 JUnit 不同,拆分成由三个不同子项目的几个不同模块组成。

    JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
    • JUnit Platform: 用于JVM上启动测试框架的基础服务,提供命令行,IDE和构建工具等方式执行测试的支持。
    • JUnit Jupiter:包含 JUnit 5 新的编程模型和扩展模型,主要就是用于编写测试代码和扩展代码。
    • JUnit Vintage:用于在JUnit 5 中兼容运行 JUnit3.x 和 JUnit4.x 的测试用例。

    2. JUnit Jupiter API 的使用

    该API的基本特性 - 注解、断言等在平时的单元测试是常用的。与JUnit4相比,部分注解的名称有改变。

    2.1 JUnit Jupiter注解

     示例代码如下:

    import lombok.extern.slf4j.Slf4j;
    import org.junit.jupiter.api.AfterAll;
    import org.junit.jupiter.api.AfterEach;
    import org.junit.jupiter.api.BeforeAll;
    import org.junit.jupiter.api.BeforeEach;
    import org.junit.jupiter.api.Disabled;
    import org.junit.jupiter.api.DisplayName;
    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import static org.junit.jupiter.api.Assertions.assertEquals;
    
    @Slf4j
    @SpringBootTest
    class Junit5demoApplicationTests {
    
        @Test
        void contextLoads() {
            log.info("default contextLoads running");
        }
    
        @BeforeAll
        public static void init() {
            log.info("Before All, only run once on the start ");
        }
    
        @AfterAll
        public static void done() {
            log.info("After All, only run once on the end ");
        }
    
        @BeforeEach
        public void setUp() throws Exception {
            log.info("Before Each, run once on the every start ");
        }
    
        @AfterEach
        public void tearDown() throws Exception {
            log.info("After Each, run once on the every end ");
        }
    
        @Test
        @DisplayName("Dummy test")
        void aTest() {
            log.info("As written, this test will always pass!");
            assertEquals(4, (2 + 2));
        }
    
        @Test
        @Disabled
        @DisplayName("A disabled test")
        void testNotRun() {
            log.info("This test will not run (it is disabled, silly).");
        }
    }

    执行结果:

     主要注解解释:

    • @RunWith 连同它的参数 JUnitPlatform.class (一个基于 JUnit 4 且理解 JUnit Platform 的 Runner )让您可以在 IDE 内运行 JUnit Jupiter 单元测试。
    • @DisplayName 告诉 JUnit 在报告测试结果时显示 String“Testing using JUnit 5”,而不是测试类的名称。
    • @BeforeAll 告诉 JUnit 在运行这个类中的所有 @Test 方法 之前 运行 init()方法 一次 。
    • @AfterAll 告诉 JUnit 在运行这个类中的所有 @Test 方法 之后 运行 done()方法 一次 。
    • @BeforeEach 告诉 JUnit 在此类中的 每个@Test 方法 之前 运行 setUp() 方法。
    • @AfterEach 告诉 JUnit 在此类中的 每个@Test 方法 之后 运行 tearDown()方法。
    • @Test 告诉 JUnit, aTest() 方法是一个 JUnit Jupiter 测试方法。
    • @Disabled 告诉 JUnit 不运行此 @Test 方法,因为它已被禁用。

    2.2 JUnit Jupiter断言

    断言 (assertion) 是 org.junit.jupiter.api.Assertions 类上的众多静态方法之一。断言用于测试一个条件,该条件必须计算为 true ,测试才能继续执行。
    如果断言失败,测试会在断言所在的代码行上停止,并生成断言失败报告。如果断言成功,测试会继续执行下一行代码。

    使用如下:

    如果不正确,会打印如下信息:

    通过上面发现一个问题,一些断言顺序执行,如果中途出现一个断言失败,那么接下去的断言就会中止,所以引入另一个断言 assetAll() 来保证所有断言能够顺利执行。使用如下:

     Junit5中新添加了对方法抛出异常的断言Assertions类中的assertThrows()和assertDoesNotThrow(),使用此方法可以对被测试方法抛出的异常进行断言测试,使用如下:

    • assertThrows()主要对被测试方法的抛出异常进行测试,测试所抛出的异常是否满足预期。
    • assertDoesNotThrow()主要用来判定被测试方法是否抛出了异常,如果抛出异常则断言失败,无异常抛出则断言成功。

    3. 运行时测试

    在实际项目开发中,有些变量需要结合上下文来测试,SpringBoot为我们提供了很好的集成 - @SpringBootTest,可以通过其实现Bean注入的功能。下面简单介绍下项目单元测试时用到的几个注解。

    3.1 @SpringBootTest + @Autowired

    这两个注解结合可以实现Bean注入,实现程序中的方法调用。

    3.2 @SpringBootTest + @MockBean

    如果测试时不想执行实际方法,例如上面例子,执行 mathService.add() 时会操作数据库,但我们不想让他执行,只需要其返回结果即可,此时可以在Bean上使用 @MockBean 注解,使用该注解之后,类中方法返回类型为数字的会返回默认值0,返回类型为字符的会返回null,如果不想使用默认值,也可以自定义返回值。

    3.3 @SpringBootTest + @SpyBean

     观察3.2 的执行可以发现@MockBean 注解的一个问题:当使用该注解时,整个类中的方法都会返回Mock,如果我们只想让配置了mock规则的方法返回Mock值,可以使用 @SpyBean 注解,使用如下:

  • 相关阅读:
    Java代码性能优化
    Kafka学习笔记(二、Kafka中的角色)
    CentOS 安装并运行Kafka
    CentOS ping name or service not known问题解决
    CentOS静态IP配置
    Kafka学习笔记(一、Kafka基础)
    sql去除中间和两边的空格
    实验二 数据更新与SQL简单查询
    实验一 完成订单数据库
    递归求P函数
  • 原文地址:https://www.cnblogs.com/zjfjava/p/13515283.html
Copyright © 2020-2023  润新知