#yyds干货盘点#JUnit5学习之二:Assumptions类

Posted 程序员欣宸

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#yyds干货盘点#JUnit5学习之二:Assumptions类相关的知识,希望对你有一定的参考价值。

欢迎访问我的GitHub

本篇概览

本文是《JUnit5学习》系列的第二篇,学习一个重要的知识点:Assumptions类,只有了解了它们,才好继续后面的学习,全篇章节如下:

  1. Assertions和Assumptions简介
  2. 写一段代码对比效果
  3. Assumptions编码
  4. 查看执行结果

    源码下载

  5. 如果您不想编码,可以在GitHub下载所有源码,地址和链接信息如下表所示:
名称 链接 备注
项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
git仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议
  1. 这个git项目中有多个文件夹,本章的应用在==junitpractice==文件夹下,如下图红框所示:

  2. ==junitpractice==是父子结构的工程,本篇的代码在==assertassume==子工程中,如下图:

    Assertions和Assumptions简介

    Assumptions和Assertions容易混淆,因此这里通过对比它们来学习:

  3. Assertions即断言类,里面提供了很多静态方法,例如assertTrue,如果assertTrue的入参为false,就会抛出AssertionFailedError异常,Junit对抛出此异常的方法判定为失败;
  4. Assumptions即假设类,里面提供了很多静态方法,例如assumeTrue,如果assumeTrue的入参为false,就会抛出TestAbortedException异常,Junit对抛出此异常的方法判定为跳过;
  5. 简单的说,Assertions的方法抛出异常意味着测试不通过,Assumptions的方法抛出异常意味着测试被跳过(为什么称为"跳过"?因为==mvn test==的执行结果被标记为==Skipped==);

    写一段代码对比效果

  6. 用代码来验证的效果最好,如下所示,一共四个方法,assertSuccess不抛出AssertionFailedError异常,assertFail抛出AssertionFailedError异常,assumpSuccess不抛出TestAbortedException异常,assumpFail抛出TestAbortedException异常
    
    package com.bolingcavalry.assertassume.service.impl;

import lombok.extern.slf4j.Slf4j;
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;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

@SpringBootTestbr/>@Slf4j
public class AssertAssumpTest

/**
 * 最简单的成功用例
 */
@Test
void assertSuccess() 
    assertEquals(2, Math.addExact(1,1));


/**
 * 最简单的失败用例
 */
@Test
void assertFail() 
    assertEquals(3, Math.addExact(1,1));


/**
 * assumeTrue不抛出异常的用例
 */
@Test
void assumpSuccess() 
    // assumeTrue方法的入参如果为true,就不会抛出异常,后面的代码才会继续执行
    assumeTrue(true);
    // 如果打印出此日志,证明assumeTrue方法没有抛出异常
    log.info("assumpSuccess的assumeTrue执行完成");
    // 接下来是常规的单元测试逻辑
    assertEquals(2, Math.addExact(1,1));


/**
 * assumeTrue抛出异常的用例
 */
@Test
void assumpFail() 
    // assumeTrue方法的入参如果为false,就会抛出TestAbortedException异常,后面就不会执行了
    assumeTrue(false, "未通过assumeTrue");
    // 如果打印出此日志,证明assumpFail方法没有抛出异常
    log.info("assumpFail的assumeTrue执行完成");
    // 接下来是常规的单元测试逻辑,但因为前面抛出了异常,就不再执行了
    assertEquals(2, Math.addExact(1,1));

2. 点击下图红框位置执行单元测试:
![在这里插入图片描述](https://s4.51cto.com/images/blog/202202/21124800_621319808ebc42232.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
3. 执行结果如下:
![在这里插入图片描述](https://s4.51cto.com/images/blog/202202/21124800_621319806582910324.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
4. 另外,在target目录,可以看到surefire插件生成的单元测试报告==TEST-com.bolingcavalry.assertassume.service.impl.AssertAssumpTest.xml==,如下图所示,testcase节点中出现了==skipped==节点:
![在这里插入图片描述](https://s4.51cto.com/images/blog/202202/21124800_62131980687e710186.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)

- 上述对比验证再次说明Assertions和Assumptions的区别:都用来对比预期值和实际值,当预期值和实际值不一致时,Assertions的测试结果是执行失败,Assumptions的测试结果是跳过(或者忽略);
### Assumptions实战
弄清楚的Assertions和Assumptions的区别,接下来趁热打铁,学习Assumptions类中几个重要的静态方法:assumeTrue、assumingThat
1. 最简单的用法如下,可见只有assumeTrue不抛出异常,后面的log.info才会执行:
```java
    @Test
    @DisplayName("最普通的assume用法")
    void tryAssumeTrue() 
        assumeTrue("CI".equals(envType));

        log.info("CI环境才会打印的assumeTrue");
    
  1. assumeTrue可以接受Supplier类型作为第二个入参,如果assumeTrue失败就会将第二个参数的内容作为失败提示:

    @Test
    @DisplayName("assume失败时带自定义错误信息")
    void tryAssumeTrueWithMessage() 
        // 第二个入参是Supplier实现,返回的内容用作跳过用例时的提示信息
        assumeTrue("CI".equals(envType),
                () -> "环境不匹配而跳过,当前环境:" + envType);
    
        log.info("CI环境才会打印的tryAssumeTrueWithMessage");
    

    效果如下图:

  2. 还有个==assumingThat==方法,可以接受Executable类型作为第二个入参,如果第一个入参为true就会执行Executable的execute方法,注意assumingThat方法的特点:==不抛出异常==,因此其所在的方法不会被跳过,这是和assumeTrue相比最大的区别(assumeTrue一旦入参为false就会抛出异常,其所在方法就被标记为跳过):

    @Test
    @DisplayName("assume成功时执行指定逻辑")
    void tryAssumingThat() 
        // 第二个入参是Executable实现,
        // 当第一个参数为true时,执行第二个参数的execute方法
        assumingThat("CI".equals(envType),
                () -> 
                    log.info("这一行内容只有在CI环境才会打印");
                );
    
        log.info("无论什么环境都会打印的tryAssumingThat");
    
    • 接下来咱们执行上述代码,看看效果;

      执行Assumptions代码

  3. 先做准备工作,本次实战的springboot工程名为==assertassume==,咱们在工程的resources目录下添加两个配置文件:application.properties和application-test.properties,位置如下图:
  4. application-test.properties内容如下:
    envType:CI
  5. application.properties内容如下:
    envType:PRODUCTION
  6. 完整的单元测试类如下,通过注解ActiveProfiles,指定了使用application-test.properties的配置,因此envType的值为==CI==:
    
    package com.bolingcavalry.assertassume.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import static org.junit.jupiter.api.Assumptions.assumingThat;

@SpringBootTestbr/>@Slf4j
@ActiveProfiles("test")
public class AssumptionsTest

@Value("$envType")
private String envType;

@Test
@DisplayName("最普通的assume用法")
void tryAssumeTrue() 
    assumeTrue("CI".equals(envType));

    log.info("CI环境才会打印的assumeTrue");


@Test
@DisplayName("assume失败时带自定义错误信息")
void tryAssumeTrueWithMessage() 
    // 第二个入参是Supplier实现,返回的内容用作跳过用例时的提示信息
    assumeTrue("CI".equals(envType),
            () -> "环境不匹配而跳过,当前环境:" + envType);

    log.info("CI环境才会打印的tryAssumeTrueWithMessage");


@Test
@DisplayName("assume成功时执行指定逻辑")
void tryAssumingThat() 
    // 第二个入参是Executable实现,
    // 当第一个参数为true时,执行第二个参数的execute方法
    assumingThat("CI".equals(envType),
            () -> 
                log.info("这一行内容只有在CI环境才会打印");
            );

    log.info("无论什么环境都会打印的tryAssumingThat");


5. 执行结果如下图,可见assume通过,所有信息都被打印出来了:
![在这里插入图片描述](https://s4.51cto.com/images/blog/202202/21124800_621319809a91a6646.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)

6. 接下来把代码中的ActiveProfiles注解那一行注释掉,如下图红框:
![在这里插入图片描述](https://s4.51cto.com/images/blog/202202/21124800_62131980d602943813.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)

7. 执行结果如下,可见tryAssumingThat方法被标记为成功,不过从日志可见assumingThat的第二个入参executable没有被执行:
![在这里插入图片描述](https://s4.51cto.com/images/blog/202202/21124800_62131980f157061716.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
- 至此,Assumptions类的常用方法体验完成,接下来的章节会继续学习其他常用类;
### 欢迎关注51CTO博客:程序员欣宸
> [学习路上,你不孤单,欣宸原创一路相伴...](https://blog.51cto.com/u_13674465)

以上是关于#yyds干货盘点#JUnit5学习之二:Assumptions类的主要内容,如果未能解决你的问题,请参考以下文章

#yyds干货盘点#JUnit5学习之六:参数化测试(Parameterized Tests)基础

#yyds干货盘点#jackson学习之六:常用类注解

#yyds干货盘点#jackson学习之九:springboot整合(配置文件)

#yyds干货盘点#jackson学习之七:常用Field注解

#yyds干货盘点#jackson学习之五:JsonInclude注解

#yyds干货盘点# react笔记之学习之完成删除功能