spring boot 单元测试JUnit5使用断言Assertions和假定Assumptions、嵌套、参数测试

这篇具有很好参考价值的文章主要介绍了spring boot 单元测试JUnit5使用断言Assertions和假定Assumptions、嵌套、参数测试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

spring boot 单元测试JUnit5使用断言Assertions和假定Assumptions、嵌套、参数测试

本文基于spirng boot 2.7.11, 大家注意自己的版本

Spring Boot 2.2.0 版本开始引入 JUnit 5 作为单元测试默认库

SpringBoot 2.4 以上版本移除了默认对 Vintage 的依赖

源码地址:https://gitcode.net/qq_39339588/springboot.git

1. 标记单元测试类和方法

@SpringBootTest注解,可以标记为测试类

@Test注解标记是测试方法

@DisplayName注解是标记个名称

@SpringBootTest
public class HelloWorldTest {
    /**
     * 断言基础
     */
    @Test
    @DisplayName("简单断言")
    public void simple() {
    }
}
2. 断言的简单使用
1)基本类型和对象的断言
/**
* 基本类型和对象的断言
*/
@Test
@DisplayName("简单断言")
public void simple() {
    Assertions.assertEquals(3, 1 + 2, "不相等");
    Assertions.assertNotEquals(3, 1 + 1, "相等了");

    //断言对象
    Assertions.assertNotSame(new Object(), new Object(), "对象相同");
    Object o = new Object();
    Assertions.assertSame(o, o, "断言不相等了");

    Assertions.assertFalse(1 > 2);
    Assertions.assertTrue(1 < 2);
    Assertions.assertNull(null);
    Assertions.assertNotNull(new Object());
}
2)数组断言
@DisplayName("数组断言")
@Test
public void array() {
    // 断言两个数组对象不相等
    Assertions.assertNotEquals(new int[]{1, 2}, new int[]{1, 2});
}
3)组合断言
@DisplayName("组合断言")
@Test
public void all() {
    // 断言所多个断言方法都正确
    Assertions.assertAll("组合断言",
            () -> Assertions.assertEquals(2, 1 + 1),
            () -> Assertions.assertTrue(1 > 0)
    );
}
4)异常断言
@DisplayName("异常断言")
@Test
public void exception() {
    // 断言方法 会出现异常
    ArithmeticException arithmeticException = Assertions.assertThrows(ArithmeticException.class, 
            () -> System.out.println(1 % 0));
    arithmeticException.printStackTrace();
}
5)超时断言
@DisplayName("超时断言")
@Test
public void timeOut() {
    // 断言方法执行不会超过1秒
    Assertions.assertTimeout(Duration.ofMillis(1000), () -> Thread.sleep(500));
}
6)快速失败断言
@DisplayName("快速失败")
@Test
public void failFast() {
    // 触发快速失败后
    AssertionFailedError ex = Assertions.assertThrows(AssertionFailedError.class, () -> {
        Assertions.fail("触发快速失败");
    });
    ex.printStackTrace();
}
3. 前置条件断言,假设假定

执行断言的前提条件,如果假定成功true,才会去执行

/**
 * 前置条件,假设假定
 */
@DisplayName("前置条件")
@Test
public void assuming() {
    String evn = "dev";
    // 执行断言的前提条件,如果假定成功true,才会去执行下一行,如果假定失败,下边的就不执行了
    Assumptions.assumeTrue(Objects.equals(evn, "dev"));
    Assumptions.assumeFalse(Objects.equals(evn, "prod"));
    System.out.println("dev和不是prod,执行了");
    Assumptions.assumeTrue(Objects.equals(evn, "dev1"));
    System.out.println("dev1,这句会忽略,不会执行输出");
}


/**
 * 假定成功true,才会去执行 执行器方法
 */
@DisplayName("前置条件That")
@Test
public void assumingThat() {
    // 假定成功,才会去执行 执行器方法
    Assumptions.assumingThat(
            Objects.equals("dev", "dev"), () -> {
                System.out.println("in dev");
            }
    );
}
4. 嵌套@Nested

内部嵌套,每次会先走外层的beforeEach,在走内部的beforeEach;支持嵌套的嵌套

@DisplayName("单元测试示例")
@SpringBootTest
public class HelloWorldTest {
    
    Stack<Object> stack;

    /**
     * 内部嵌套,每次会先走外层的beforeEach,在走内部的beforeEach
     */
    @DisplayName("内部嵌套测试")
    @Nested
    class InnerTest {
        @BeforeEach
        void newStack() {
            // 创建一个栈对象
            stack = new Stack<>();
        }

        @DisplayName("检查是否为空")
        @Test
        void isEmpty() {
            Assertions.assertTrue(stack.isEmpty());
        }

        @DisplayName("抛出一个栈pop异常")
        @Test
        void throwExceptionWhenPop() {
            Assertions.assertThrows(EmptyStackException.class, stack::pop);
        }

        @DisplayName("抛出一个栈peek异常")
        @Test
        void throwExceptionWhenPeek() {
            Assertions.assertThrows(EmptyStackException.class, stack::peek);
        }

        @Nested
        @DisplayName("内部的内部嵌套测试")
        class InnerInnerTest {
            String item = "item";

            @BeforeEach
            void pushAnItem() {
                // 放入一个元素
                stack.push(item);
            }

            @DisplayName("不为空了")
            @Test
            void isNotEmpty() {
                Assertions.assertFalse(stack.isEmpty());
            }

            @DisplayName("取出一个来,用pop")
            @Test
            void returnItemByPop() {
                Assertions.assertEquals(item, stack.pop());
                Assertions.assertTrue(stack.isEmpty());
            }

            @DisplayName("取出一个来,用peek")
            @Test
            void returnItemByPeek() {
                Assertions.assertEquals(item, stack.peek());
                Assertions.assertFalse(stack.isEmpty());
            }
        }

    }
5. 参数化测试

参数化测试,让单元测试的方法支持接收传入的参数

将可以使用不同的参数进行多次单元测试,有多少套参数,就执行多少次单元测试

而不需要每新增一个参数就新增一个单元测试,省去了很多冗余代码

1)@ValueSource注解,基本类型入参
/**
 * @ValueSource:为参数化测试指定入参来源,支持八大基础类以及String类型,Class类型
 * @param params
 */
@DisplayName("参数化测试,值来源")
@ParameterizedTest
@ValueSource(strings = {"a", "b", "c"})
public void parameterizedTest(String params) {
    // 会执行3次,分别执行a,b,c
    System.out.println(params);
    Assertions.assertTrue(StringUtils.isNotBlank(params));
}
2)@NullSource注解,null入参
/**
 * null入参
 *
 * @param params
 */
@DisplayName("null的入参")
@ParameterizedTest
@NullSource
public void testNull(String params) {
    Assertions.assertNull(params);
}
3)@EnumSource注解,枚举入参
/**
 * 枚举入参,会把枚举遍历一遍,分别执行一次方法
 */
@DisplayName("枚举的入参")
@ParameterizedTest
@EnumSource(TestEnum.class)
public void testEnumSource(TestEnum params) {
    System.out.println("state:" + params.state + ",msg:" + params.msg);
    // state:1,msg:好
    // state:2,msg:不好
    Assertions.assertNotNull(params);
}

/**
 * 枚举类
 */
@Getter
@AllArgsConstructor
public enum TestEnum {
    GOOD(1, "好"),
    BAD(2, "不好");
    int state;
    String msg;
}
4)@CsvSource注解,多参数入参
@DisplayName("参数化测试,@CsvSource")
@ParameterizedTest
@CsvSource({"a,b,c"})
void parameterizedTestCsvSource(String a, String b, String c) {
    // 默认使用逗号分隔
    System.out.println(a + b + c);
    Assertions.assertNotNull(a);
}

@DisplayName("参数化测试,@CsvSource2")
@ParameterizedTest
@CsvSource(value = {"a,b,c-D"}, delimiterString = "-")
void parameterizedTestCsvSource2(String abc, String d) {
    // 默认使用逗号分隔,指定分隔符"-"
    System.out.println(abc);
    System.out.println(d);
    Assertions.assertNotNull(abc);
    // a,b,c
    // D
}
5)@CsvFileSource,参数文件入参

可以把文件中的内容当做参数,批量来执行,下边附带了my.csv和my2.csv文件内容

注意,要在测试目录下,新建resources目录,再放入my.csv和my2.csv文件

/**
 * 参数文件
 *
 * @param methodName
 */
@DisplayName("参数化测试,@CsvFileSource")
@ParameterizedTest
@CsvFileSource(resources = "/my.csv")
void parameterizedTestWithCsvFileSource(String methodName) {
    // 测试目录下,新建resources目录
    System.out.println(methodName);
    Assertions.assertNotNull(methodName);
}

@DisplayName("参数化测试,@CsvFileSource")
@ParameterizedTest
@CsvFileSource(resources = "/my2.csv", delimiterString = "|")
void parameterizedTestWithCsvFileSource2(String name, Integer age) {
    // 测试目录下,新建resources目录
    System.out.println(name + ":" + age);
    Assertions.assertNotNull(name);
    // a:18
    // b:17
    // c:20
}

my.csv文件

1
2
3
4

my2.csv

a|18
b|17
c|20
6)@MethodSource注解,方法返回值入参

把一个方法的返回值,作为测试用例方法的参数文章来源地址https://www.toymoban.com/news/detail-513282.html

/**
 * 动态参数
 */
@DisplayName("参数化测试,方法来源")
@ParameterizedTest
@MethodSource("method1") // 如果不指定方法名称,会去找与自己相同名称的静态方法
public void parameterizedTestWithMethodParam(String params) {
    // MethodSource("method1") 接收这个方法的返回值,之后会执行2次,a,b
    System.out.println(params);
    Assertions.assertNotNull(params);
}

static Stream<String> method1() {
    return Stream.of("a", "b");
}


@DisplayName("参数化测试,方法来源,多参数")
@ParameterizedTest
@MethodSource // 如果不指定方法名称,会去找相同名称的静态方法
public void parameterizedTestWithMethodMultipleParams(String name, Integer age) {
    System.out.println(name + ":" + age);
    // a:18
    // b:17
    // c:20
    Assertions.assertNotNull(name);
}

static Stream<Arguments> parameterizedTestWithMethodMultipleParams() {
    return Stream.of(
            Arguments.arguments("a", 18),
            Arguments.arguments("b", 17),
            Arguments.arguments("c", 20)
    );
}

7) @ArgumentsSource注解,自定义参数入参
/**
 * 实现ArgumentsProvider接口,并在测试方法上使用@ArgumentsSource注解。
 */
@DisplayName("@ArgumentsSource注解")
@ParameterizedTest
@ArgumentsSource(MyArgumentsProvider.class)
public void testArgumentsSource(String name, int age) {
    System.out.println(name + ":" + age);
    // aa:18
    // bb:20
    // cc:30
    Assertions.assertNotNull(name);
}

到了这里,关于spring boot 单元测试JUnit5使用断言Assertions和假定Assumptions、嵌套、参数测试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring Cloud中Controller单元测试 Junit5 & MockMvc

    在Spring Cloud中进行Controller的单元测试,使用Junit5和Mock。 Controller: 方式一:使用@SpringBootTest + @AutoConfigureMockMvc 方式二:使用@WebMvcTest + @ImportAutoConfiguration(RefreshAutoConfiguration.class) 解决 No Scope registered for scope name \\\'refresh\\\' 异常 注入Mockmvc方式有两种 方式一:(@AutoConfigureMockMvc / @

    2024年02月16日
    浏览(38)
  • SpringBoot单元测试断言 assertions

    断言(assertions)是测试方法中的核心部分,用来对测试需要满足的条件进行验证。这些断言方法都是 org.junit.jupiter.api.Assertions 的静态方法。JUnit 5 内置的断言可以分成如下几个类别: 1、简单断言 2、数组断言 通过 assertArrayEquals 方法来判断两个对象或原始类型的数组是否相等

    2024年02月05日
    浏览(45)
  • 【单元测试】如何使用 JUnit5 框架?

      Junit5是一个用于在Java平台上进行单元测试的框架。JUnit 5 框架主要由三部分组成:JUnit Platform、JUnit Jupiter 和 JUnit Vintage。 JUnit Platform:定义了测试引擎的 API,是 JVM 上用于启动测试框架的基础服务,支持通过 IDE、构建工具、命令行等方式运行单元测试。 JUnit Jupiter:包含

    2024年04月10日
    浏览(45)
  • SpringBoot单元测试--Mockito+Junit5框架使用

    作为程序员为了提前发现代码bug,优化代码; 通常我们写完某个功能模块代码后都需要写单元测试对代码块进行测试(特别是敏捷开发中);Java项目最常用的单元测试框架即为Junit(目前最新版本为Junit5),SpringBoot本身也整合了该框架。在写单元测试时代码块中的调到第三方接口方

    2024年02月02日
    浏览(46)
  • 在 Java 中使用JUnit5进行单元测试和自动化测试

    单元测试和自动化测试是现代软件开发过程中必不可少的环节,可以提高代码质量和开发效率。JUnit5是Java中流行的单元测试框架,本文将介绍如何在Java中使用JUnit5进行单元测试和自动化测试。 2.1 单元测试的基本概念和原理 单元测试是一种测试方法,用于对软件系统中的最

    2024年02月03日
    浏览(45)
  • 如何在 Java 中使用JUnit5进行单元测试和自动化测试

    单元测试和自动化测试是现代软件开发过程中必不可少的环节,可以提高代码质量和开发效率。JUnit5是Java中流行的单元测试框架,本文将介绍如何在Java中使用JUnit5进行单元测试和自动化测试。 单元测试是一种测试方法,用于对软件系统中的最小可测试单元进行测试。这些单

    2024年02月05日
    浏览(57)
  • Spring Boot使用JUnit和Mockito进行Service层单元测试

      在平时的开发当中,一个项目往往包含了大量的方法,可能有成千上万个。如何去保证这些方法产生的结果是我们想要的呢?那么在SpringBoot项目中我们是如何对Service层的方法进行测试的呢?   单元测试是一种软件测试方法,用于测试代码的最小可测试单元。在Java开发

    2024年02月03日
    浏览(55)
  • 单元测试框架——Junit5

    Junit是一个开源的用于Java语言的单元测试框架,也是Java方向使用最广泛的单元测试框架。 在pom.xml中引入Junit5相关依赖 @Test :表示一个方法/用例 BeforeEach :表示被注解的方法在其它所有方法执行前都要执行一遍,也就是说其它方法有3个它就要执行3遍 @BeforeAll :表示被注解的

    2024年02月11日
    浏览(44)
  • springboot项目使用Junit5 + mockito + jacoco 实现单元测试以及代码覆盖率检查

    在创建springboot项目时会默认添加spring-boot-starter-test依赖,其中已经包含了junit、mockito依赖,根据springboot版本的不同junit和mockito的版本也会有所不同 先说一下各自功能: junit只说一点,junt4和junit5的注解不同,使用方式略有差异,其他不赘述了,基本用法都懂。 mockito是mock的

    2023年04月23日
    浏览(58)
  • Junit5单元测试框架详解

    前面我们学习了Selenium自动化测试框架,但是有的时候测试用例会很多,我们需要一个工具来管理这些测试用例,而Junit就是一个很好的管理工具,简单点来说,Junit就是一个针对Java的单元测试框架; 目录 一. 关于Junit5 二. Junit使用 2.1 添加Maven依赖 2.2 注解 2.3 断言 2.4 套件

    2024年02月06日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包