Spring Boot 单元测试(六)Assertions & Assumptions

1,571 阅读1分钟

Assertions 是断言类,提供了断言相关的静态方法,如assertTrue,当assertTrue参数为false时会抛出AssertionFailedError异常,JUnit5 对抛出此异常的方法判定为Failures(失败)。

Assumptions 是假设类,提供了假设相关的静态方法,如assumeTrue,当assumeTrue参数为false时会抛出TestAbortedException异常,JUnit5 对抛出此异常的方法判定为Skipped(跳过)。

Assertions

常用方法:

  • assertAll:断言所有都不会抛出异常。

    @Test
    public void test() {
        Assertions.assertAll(
                "错误提示信息",
                () -> Assertions.assertTrue(true),
                () -> Assertions.assertEquals(1, 1.0),
                () -> Assertions.assertNull(""));
    }
    

    测试运行结果:

    [ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.001 s <<< FAILURE! - in com.example.demo.UnitTest
    [ERROR] test  Time elapsed: 0.001 s  <<< FAILURE!
    org.opentest4j.MultipleFailuresError:
    错误提示信息 (1 failure)
            org.opentest4j.AssertionFailedError: expected: <null> but was: <>
            at com.example.demo.UnitTest.test(UnitTest.java:10)
    
  • assertArrayEquals:断言期望的数组和实际数据相等。

  • assertDoesNotThrow:断言测试方法不会抛出异常。

    @Test
    public void test() {
        Assertions.assertDoesNotThrow(
                () -> 1 / 0,
                "不应该抛出异常");
    }
    

    测试运行结果:

    [ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.001 s <<< FAILURE! - in com.example.demo.UnitTest
    [ERROR] test  Time elapsed: 0 s  <<< FAILURE!
    org.opentest4j.AssertionFailedError: 不应该抛出异常 ==> Unexpected exception thrown: java.lang.ArithmeticException: / by zero at com.example.demo.UnitTest.test(UnitTest.java:10)
    Caused by: java.lang.ArithmeticException: / by zero
            at com.example.demo.UnitTest.lambda$0(UnitTest.java:11)
            at com.example.demo.UnitTest.test(UnitTest.java:10)
    
  • assertEquals:断言期望结果和实际结果相等。

  • assertFalse:断言实际结果为false

  • assertInstanceOf:断言对象是期望类型。

    @Test
    public void test() {
        Assertions.assertInstanceOf(String.class, "");
    }
    
  • assertIterableEquals:断言期望的集合和实际数据相等,包括元素的数量、顺序以及元素本身。

  • assertLinesMatch:断言期望的字符串列表和实际列表匹配。

    @Test
    public void test() {
        List<String> strList1 = Arrays.asList("A", "B", "C");
        List<String> strList2 = Arrays.asList("A", "B", "C");
        Assertions.assertLinesMatch(strList1, strList2);
    }
    
  • assertNotEquals:断言期望结果和实际结果不相等。

  • assertNotNull:断言实际结果不为null

  • assertNotSame:断言预期引用和实际引用不是同一个对象。

    @Test
    public void test() {
        String str = "";
        Object obj = str;
        Assertions.assertNotSame(str, obj);
    }
    
  • assertNull:断言实际结果为null

  • assertSame:断言预期引用和实际引用是同一个对象。

  • assertThrows:断言测试方法会抛出期望异常。

    @Test
    public void test() {
        Assertions.assertThrows(
                NullPointerException.class,
                () -> System.out.println(1 / 0),
                "");
    }
    

    测试运行结果:

    [ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.001 s <<< FAILURE! - in com.example.demo.UnitTest
    [ERROR] test  Time elapsed: 0 s  <<< FAILURE!
    org.opentest4j.AssertionFailedError: Unexpected exception type thrown ==> expected: <java.lang.NullPointerException> but was: <java.lang.ArithmeticException>
         at com.example.demo.UnitTest.test(UnitTest.java:10)
    Caused by: java.lang.ArithmeticException: / by zero
         at com.example.demo.UnitTest.lambda$0(UnitTest.java:12)
         at com.example.demo.UnitTest.test(UnitTest.java:10)
    
  • assertThrowsExactly:断言测试方法会抛出期望异常,与assertThrows的区别可以从以下代码示例中看出。

    @Test
    public void test() {
        Assertions.assertThrows(
                Exception.class,
                () -> System.out.println(1 / 0));
        Assertions.assertThrowsExactly(
                ArithmeticException.class,
                () -> System.out.println(1 / 0));
    }
    
  • assertTimeout:断言测试方法超时时间。

    @Test
    public void test() {
        Assertions.assertTimeout(
                Duration.ofSeconds(1),
                () -> Thread.currentThread().sleep(2000));
    }
    

    测试运行结果:

    [ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 2.007 s <<< FAILURE! - in com.example.demo.UnitTest
    [ERROR] test  Time elapsed: 2.007 s  <<< FAILURE!
    org.opentest4j.AssertionFailedError: execution exceeded timeout of 1000 ms by 1011 ms
         at com.example.demo.UnitTest.test(UnitTest.java:12)
    
  • assertTimeoutPreemptively:断言测试方法超时时间,一旦测试方法执行过期望超时时间还未结束,会立即返回断言失败,不会等到方法执行完成。

    @Test
    public void test() {
        Assertions.assertTimeoutPreemptively(
                Duration.ofSeconds(1),
                () -> Thread.currentThread().sleep(2000));
    }
    

    测试运行结果:

    [ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.005 s <<< FAILURE! - in com.example.demo.UnitTest
    [ERROR] test  Time elapsed: 1.004 s  <<< FAILURE!
    org.opentest4j.AssertionFailedError: execution timed out after 1000 ms
         at com.example.demo.UnitTest.test(UnitTest.java:12)
    Caused by: org.junit.jupiter.api.AssertTimeout$ExecutionTimeoutException: Execution timed out in thread junit-timeout-thread-1
         at app//com.example.demo.UnitTest.lambda$0(UnitTest.java:14)
    

    对比assertTimeout测试运行结果可以看出两者差异。

  • assertTrue:断言实际结果为true

以上方法均有多种重载形式。

除使用 JUnit5 提供的Assertions外,还可以使用第三方库提供的断言类,如 AssertJ 提供的Assertions类。

Assumptions

常用方法:

  • assumeFalse:假设给定条件为false
    @Test
    public void test() {
        Assumptions.assumeFalse(() -> 1 == 1.0);
    }
    
    测试运行结果:
    [WARNING] Tests run: 2, Failures: 0, Errors: 0, Skipped: 1
    
  • assumeTrue:假设给定条件为true
    @Test
    public void test() {
        Assumptions.assumeTrue(() -> 1 == 1.0);
    }
    
  • assumeThat:只有在给定假设有效时执行相应动作。
    @Test
    public void test() {
        Assumptions.assumingThat(
                "zh".equals(System.getProperty("user.language")),
                () -> System.out.println("中文"));
    }
    
    说明:只有在当前系统属性user.languagezh时打印输出中文