SpringBoot2——单元测试

在SpringBoot2中,它自带了单元测试的依赖,使用的单元测试不再是Junit4,而是Junit5,并且在SpringBoot2.4之后,SpringBoot不在支持Junit4,如果想使用Junit4需要另外导入依赖

Junit5常用注解

  • **@Test 😗*表示方法是测试方法。但是与JUnit4的@Test不同,他的职责非常单一不能声明任何属性,拓展的测试将会由Jupiter提供额外测试

  • **@ParameterizedTest 😗*表示方法是参数化测试,下方会有详细介绍

  • **@RepeatedTest 😗*表示方法可重复执行,下方会有详细介绍

  • **@DisplayName 😗*为测试类或者测试方法设置展示名称

  • **@BeforeEach 😗*表示在每个单元测试之前执行

  • **@AfterEach 😗*表示在每个单元测试之后执行

  • **@BeforeAll 😗*表示在所有单元测试之前执行

  • **@AfterAll 😗*表示在所有单元测试之后执行

  • **@Tag 😗*表示单元测试类别,类似于JUnit4中的@Categories

  • **@Disabled 😗*表示测试类或测试方法不执行,类似于JUnit4中的@Ignore

  • **@Timeout 😗*表示测试方法运行如果超过了指定时间将会返回错误

  • **@ExtendWith 😗*为测试类或测试方法提供扩展类引用

想要使用Junit5,必须要在测试类前标注SpringBootTest注解

@DisplayName("测试常用注解")
@SpringBootTest
public class Junit5Test {
    @Test
    @DisplayName("展示名称")
    void displayName(){
        System.out.println("111");
    }
    @Test
    @Disabled
    @DisplayName("方法2")
    void test2(){
        System.out.println("222");
    }
    @Test
    @DisplayName("超时报错")
    @Timeout(value = 1,unit = TimeUnit.SECONDS)
    void test3() throws InterruptedException {
        Thread.sleep(2000);
    }
    @BeforeEach
    void beforeEach(){
        System.out.println("在测试方法前执行");
    }
    @AfterEach
    void afterEach(){
        System.out.println("在测试方法后执行");
    }
    @BeforeAll
    static void beforeAll(){
        System.out.println("在所有测试方法前执行");
    }
    @AfterAll
    static void afterAll(){
        System.out.println("在所有测试方法后执行");
    }
}

断言(assertions)

小黄的个人理解,断言类似与判断,如果判断成立,则无事发生,否则报错

assertions类中的方法大多是静态方法,可以直接调用

@SpringBootTest
@DisplayName("断言测试")
public class AssertionsTest {
    @Test
    @DisplayName("测试assertEquals")
    void test1(){
        int a = 3 + 2;
        assertEquals(6, a, "数学运算错误");
    }
    @Test
    @DisplayName("测试assertSame")
    void test2(){
        Object obj1 = new Object();
        Object obj2 = new Object();
        assertSame(obj1,obj2,"两个对象不同");
    }
    @Test
    @DisplayName("数组断言")
    void test3(){
        assertArrayEquals(new int[]{1,2},new int[]{2,1},"两个数组不同");
    }
    @Test
    @DisplayName("组合断言")
    void test4(){
        assertAll("数学运算",()->{
            assertEquals(6, 3+3, "数学运算错误");
        },()->{
            assertNotEquals(6, 3+3, "数学运算正确");
        });
    }
    @Test
    @DisplayName("超时断言")
    void test5(){
        //设置超过1秒报错
        assertTimeout(Duration.ofMillis(1000),()->{
            Thread.sleep(500);
        });
    }
    @Test
    @DisplayName("快速失败")
    void test6(){
        if(1==1){
            fail("快速失败");
        }
    }
}

前置条件(assumptions)

前置条件有点像if判断,如果条件成立,接下去执行测试代码,如果不成立则不执行往后代码

@SpringBootTest
@DisplayName("前置条件")
public class AssumptionsTest {
    @Test
    @DisplayName("")
    void test1(){
        //如果条件成立,执行输出语句
        Assumptions.assumeTrue(1==1);
        System.out.println("111");
        //如果条件返回值不为false则终止后面的代码
        Assumptions.assumeFalse(1==1);
        System.out.println("222");
    }
}

嵌套测试

JUnit 5 可以通过 Java 中的内部类和@Nested 注解实现嵌套测试,从而可以更好的把相关的测试方法组织在一起。在内部类中可以使用@BeforeEach 和@AfterEach 注解,而且嵌套的层次没有限制。

@DisplayName("A stack")
class TestingAStackDemo {

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

参数化测试

参数化测试是JUnit5很重要的一个新特性,它使得用不同的参数多次运行测试成为了可能,也为我们的单元测试带来许多便利。

利用**@ValueSource**等注解,指定入参,我们将可以使用不同的参数进行多次单元测试,而不需要每新增一个参数就新增一个单元测试,省去了很多冗余代码。

@ValueSource: 为参数化测试指定入参来源,支持八大基础类以及String类型,Class类型

@NullSource: 表示为参数化测试提供一个null的入参

@EnumSource: 表示为参数化测试提供一个枚举入参

@CsvFileSource:表示读取指定CSV文件内容作为参数化测试入参

@MethodSource:表示读取指定方法的返回值作为参数化测试入参(注意方法返回需要是一个流)

    @ParameterizedTest
    @DisplayName("参数化测试")
    @ValueSource(ints = {1,2,3,4,5})
    void test2(int i){
        //i代表遍历ints中的数字
        System.out.println(i);
    }

    @ParameterizedTest
    @DisplayName("参数化测试——方法")
    @MethodSource("method")
    void test3(String str){
        System.out.println(str);
    }

    static Stream<String> method() {
        return Stream.of("apple", "banana");
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值