springboot学习[版本2.6.2]单元测试JUnit5 day7-1

单元测试JUnit5

  • 版本
  • 文档
  • JUnit5依赖
  • Spring Boot整合JUnit5之后
    • 编写测试方法
      • @Autowired自动装配注入
      • @Transactional标注测试方法,测试结束进行回滚
    • JUnit5常用注解
      • 1.@Test
      • 2.@ParameterizedTest
      • 3. @RepeatedTest()
      • 4.@DisplayName()
      • 5. @BeforeEach
      • 6.@BeforeAll
      • 7. @AfterAll
      • 8. @AfterEach
      • Before和After的集中展示
      • 9.@Tag()
      • 10. @Disabled
      • 11. @Timeout()
      • 12. @ExtendWith()
    • 完整常用注解测试类
  • 断言机制
    • 简单断言
      • assertEquals()方法
      • assertSame()方法
      • assertNotEquals()判断两个对象的原始类型是否不同
      • assertNotSame()判断两个对象是否不是同一个对象
      • assertTrue()判断给定的布尔值是否为True
      • assertFalse()判断给定的布尔值是否为false
      • assertNull()判断给定的对象引用是否为 NULL
      • assertNotNull()判断给定的对象引用是否不为Null
    • 数组断言assertArrayEquals()
    • 组合断言assertAll()
    • 异常断言assertThrows()
    • 超时断言assertTimeout()
    • 快速失败fail()
  • 前置条件assumptions
    • 区别
  • 嵌套测试 Nested Tests
    • 文档
      • 注意点
  • 参数化测试
    • 文档
    • 参数化测试常用注解
      • 1. @ValueSource
      • 2. @NullSource
      • 3. @EnumSource
      • 4. CsvFileSource
      • 5. MethodSource

版本

在Spring Boot2.4之后就不兼容JUnit4及以前的版本了

文档

https://junit.org/junit5/docs/current/user-guide/

JUnit5依赖

/org.springframework.boot/spring-boot-starter-test -->
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-testartifactId>
    <version>2.6.2version>
    <scope>testscope>
dependency>

Spring Boot整合JUnit5之后

编写测试方法

需要在方法上使用@Test注解

@Autowired自动装配注入

@Transactional标注测试方法,测试结束进行回滚

JUnit5常用注解

1.@Test

用于声明该方法是测试方法

2.@ParameterizedTest

参数化测试,请看下面

3. @RepeatedTest()

对测试方法进行重复测试

    @RepeatedTest(value = 2)
    @DisplayName("测试 @DisplayName()")
    @Test
    void testDisplayName(){
        System.out.println("这是 @DisplayName()的测试!");
    }

springboot学习[版本2.6.2]单元测试JUnit5 day7-1_第1张图片

4.@DisplayName()

用于指定测试方法或测试类的展示名称

package com.example.day6;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class JUnit5Test {

    @DisplayName("测试 @DisplayName()")
    @Test
    void testDisplayName(){
        System.out.println("这是 @DisplayName()的测试!");
    }
}

springboot学习[版本2.6.2]单元测试JUnit5 day7-1_第2张图片

5. @BeforeEach

用于在每个测试方法之前进行操作

@BeforeEach
    void testBeforeEach(){
        System.out.println("测试即将开始--->");
    }

springboot学习[版本2.6.2]单元测试JUnit5 day7-1_第3张图片

6.@BeforeAll

用于在所有测试方法之前进行操作

 @BeforeAll
    static void testBeforeAll(){
        System.out.println("**********测试开始**********");
    }

7. @AfterAll

用于在所有测试方法之后进行操作

@AfterAll
    static void testAfterAll(){
        System.out.println("***********测试结束**********");
    }

8. @AfterEach

用于在每个测试方法之后进行操作

@AfterEach
    void testAfterEach(){
        System.out.println("测试结束--->");
    }

Before和After的集中展示

springboot学习[版本2.6.2]单元测试JUnit5 day7-1_第4张图片

9.@Tag()

用于表示单元测试类别

10. @Disabled

用于取消测试方法或测试类(不执行)

@Disabled
    @DisplayName("测试2")
    @Test
    void testDisplayName2(){
        System.out.println("这是 @DisplayName()的第二个测试!");
    }

在这里插入图片描述

11. @Timeout()

用于设定测试方法若超出规定事件就会返回错误

		@DisplayName("TimeOut的测试方法")
    @Timeout(value = 5,unit = TimeUnit.MILLISECONDS)
    @Test
    void testTimeOut(){
        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("@TimeOut 的测试");
    }

springboot学习[版本2.6.2]单元测试JUnit5 day7-1_第5张图片

12. @ExtendWith()

用于为测试类或测试方法提供扩展类引用
我们看到SpringBoot里使用的@SpringBootTest注解就有这个
springboot学习[版本2.6.2]单元测试JUnit5 day7-1_第6张图片

完整常用注解测试类

package com.example.day6;

import org.junit.jupiter.api.*;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.concurrent.TimeUnit;

@SpringBootTest
public class JUnit5Test {

    @DisplayName("TimeOut的测试方法")
    @Timeout(value = 5,unit = TimeUnit.MILLISECONDS)
    @Test
    void testTimeOut(){
        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("@TimeOut 的测试");
    }

    @RepeatedTest(value = 2)
    @DisplayName("测试 @DisplayName()")
    @Test
    void testDisplayName(){
        System.out.println("这是 @DisplayName()的测试!");
    }

    @Disabled
    @DisplayName("测试2")
    @Test
    void testDisplayName2(){
        System.out.println("这是 @DisplayName()的第二个测试!");
    }

    @BeforeEach
    void testBeforeEach(){
        System.out.println("测试即将开始--->");
    }

    @AfterEach
    void testAfterEach(){
        System.out.println("测试结束--->");
    }

    @BeforeAll
    static void testBeforeAll(){
        System.out.println("**********测试开始**********");
    }

    @AfterAll
    static void testAfterAll(){
        System.out.println("***********测试结束**********");
    }
}

断言机制

用于对测试需要满足的条件进行验证(检测业务逻辑返回的数据是否合理)
断言方法都在junit.jupiter.api.Assertions的静态方法中

当测试出现问题之后会给测试者一个详细的测试报告
断言情况下前面断言出现问题后面则不会执行

简单断言

assertEquals()方法

用于判断传入的两个对象原始类型是否相同

public static void assertEquals(int expected, int actual, String message) {
        AssertEquals.assertEquals(expected, actual, message);
    }

第三个参数是可以用来设置测试失败后自定义的信息打印

assertEquals(judgeNum,10,"测试结果错误");
package com.example.day6;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Scanner;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
public class JUnit5AssertionTest {

    @DisplayName("简单断言测试")
    @Test
    void simpleAssertionTest(){
        int judgeNum = judge(2, 5);
        assertEquals(judgeNum,10);
    }

    int judge(int num1,int num2){
        int num = num1>num2?num1:num2;
        return num;
    }
}

springboot学习[版本2.6.2]单元测试JUnit5 day7-1_第7张图片

assertSame()方法

用于判断两个对象是否是同一个对象

@DisplayName(" assertSame 断言测试")
    @Test
    void assertSameTest(){
        Object obj1 = new Object();
        Object obj2 = new Object();
        assertSame(obj1,obj2,"测试失败");
    }

springboot学习[版本2.6.2]单元测试JUnit5 day7-1_第8张图片

assertNotEquals()判断两个对象的原始类型是否不同

assertNotSame()判断两个对象是否不是同一个对象

assertTrue()判断给定的布尔值是否为True

assertFalse()判断给定的布尔值是否为false

assertNull()判断给定的对象引用是否为 NULL

assertNotNull()判断给定的对象引用是否不为Null

数组断言assertArrayEquals()

判断两个数组中的值是否相同
传入的两个数组一定要是同一个类型的

    @Test
    void assertArray() {
        assertArrayEquals(new int[]{1, 6}, new int[]{6, 1}, "测试失败");
    }

组合断言assertAll()

assertAll方法可以通过lambda表达式进行判断

    @Test
    void assertAllTest(){
        assertAll("test",
                ()-> assertArrayEquals(new double[]{1.5,8},new double[]{1,8}),
                ()-> assertNotSame(8,8));
    }

springboot学习[版本2.6.2]单元测试JUnit5 day7-1_第9张图片

异常断言assertThrows()

断定业务逻辑一定出现异常

    @DisplayName("异常断言")
    @Test
    void assertThrowsTest(){
        assertThrows(Exception.class,()->{int i = 1/0;},"异常未出现");
    }

超时断言assertTimeout()

断定在设置的时间里一定会成功超时则出现异常

@DisplayName("超时断言")
    @Test
    void timeOutTest(){
        assertTimeout(Duration.ofSeconds(1),()->{Thread.sleep(800);});
    }

快速失败fail()

通过使用fail方法直接让测试失败

    @Test
    void failTest(){
        fail("我直接失败怎么说?");
    }

在这里插入图片描述

前置条件assumptions

类似于断言,其实就是测试方法执行的前提条件若不满足则无法测试

区别

若不满足前置条件则测试终止而非失败

        @DisplayName("前置条件的测试")
    @Test
    void assumptionTest(){
        Assumptions.assumeTrue(false,"前提不是true");
        System.out.println("方法执行成功");
    }

springboot学习[版本2.6.2]单元测试JUnit5 day7-1_第10张图片

嵌套测试 Nested Tests

文档

https://junit.org/junit5/docs/current/user-guide/#writing-tests-nested

@Nested 测试为测试编写者提供了更多的能力来表达多组测试之间的关系。这种嵌套测试使用Java的嵌套类,并促进了对测试结构的分层思考。

注意点

  1. 当我们要写嵌套测试的时候要在书写嵌套测试的“大”方法上添加注释@Nested
  2. 嵌套测试的情况下,外层的Test无法驱动内层
@Nested
class Outter{
	@Test
	void test1(){
		...
	}
	@Test
	void test2(){
		...
	}
	@Test
	void test3(){
		...
	}
}
package com.example.day6;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.EmptyStackException;
import java.util.Stack;

import static org.junit.jupiter.api.Assertions.*;

@DisplayName("嵌套测试")
public class NestedTestDemo {
    Stack<Object> stack;

    @Test
    @DisplayName("is instantiated with new Stack()")
    void isInstantiatedWithNew() {
        new Stack<>();
    }

    @Nested
    @DisplayName("when new")
    class WhenNew {

        @BeforeEach
        void createNewStack() {
            stack = new Stack<>();
        }

        @Test
        @DisplayName("is empty")
        void isEmpty() {
            assertTrue(stack.isEmpty());
        }

        @Test
        @DisplayName("throws EmptyStackException when popped")
        void throwsExceptionWhenPopped() {
            assertThrows(EmptyStackException.class, stack::pop);
        }

        @Test
        @DisplayName("throws EmptyStackException when peeked")
        void throwsExceptionWhenPeeked() {
            assertThrows(EmptyStackException.class, stack::peek);
        }

        @Nested
        @DisplayName("after pushing an element")
        class AfterPushing {

            String anElement = "an element";

            @BeforeEach
            void pushAnElement() {
                stack.push(anElement);
            }

            @Test
            @DisplayName("it is no longer empty")
            void isNotEmpty() {
                assertFalse(stack.isEmpty());
            }

            @Test
            @DisplayName("returns the element when popped and is empty")
            void returnElementWhenPopped() {
                assertEquals(anElement, stack.pop());
                assertTrue(stack.isEmpty());
            }

            @Test
            @DisplayName("returns the element when peeked but remains not empty")
            void returnElementWhenPeeked() {
                assertEquals(anElement, stack.peek());
                assertFalse(stack.isEmpty());
            }
        }
    }
}

参数化测试

能够使用不同的参数进行多次运行测试
使用注解指定入参
它们的声明方式与常规的 @Test 方法一样,但使用 @ParameterizedTest 注释

文档

https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests

参数化测试常用注解

1. @ValueSource

指定入参来源

2. @NullSource

提供一个Null入参

3. @EnumSource

提供一个枚举入参

4. CsvFileSource

提供一个csv文件内容作为参数入参

5. MethodSource

读取指定方法的返回值作为参数化测试的入参(流)

package com.example.day6;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EmptySource;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.NullSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.junit.platform.commons.util.StringUtils;


import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

@DisplayName("参数化测试")
public class ParamTestDemo {

    @ParameterizedTest
    @ValueSource(ints = { 1, 2, 3 })
    void testWithValueSource(int argument) {
        assertTrue(argument > 0 && argument < 4);
    }


    @ParameterizedTest
    @ValueSource(strings = { "racecar", "radar", "able was I ere I saw elba" })
    void palindromes(String candidate) {
        System.out.println(candidate);
    }




    @ParameterizedTest
    @NullSource
    @EmptySource
    @ValueSource(strings = { " ", "   ", "\t", "\n" })
    void nullEmptyAndBlankStrings(String text) {
        assertTrue(text == null || text.trim().isEmpty());
    }



    @ParameterizedTest
    @EnumSource(ChronoUnit.class)
    void testWithEnumSource(TemporalUnit unit) {
        assertNotNull(unit);
    }


}

springboot学习[版本2.6.2]单元测试JUnit5 day7-1_第11张图片

你可能感兴趣的:(#,SpringBoot,笔记,Java学习,单元测试,spring,boot,java)