JUnit5概览

1. 概述

JUnit是最流行的Java单元测试框架之一,因此当新的主要版本出现时,它在开发人员社区中是一个大问题。JUnit 5的alpha版本于2月初发布,它包含了许多令人兴奋的创新。

本文将探讨此版本的新功能,以及与以前版本的主要区别。

2. 依赖关系和设置

安装JUnit 5非常简单。只需将以下依赖项添加到您的pom.xml

1
2
3
4
5
6
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.1.0</version>
<scope>test</scope>
</dependency>

但是,目前还没有IDE支持JUnit 5,因此您还必须指定构建脚本:

1
2
3
4
5
6
7
8
9
10
11
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.0.2</version>
</dependency>
</dependencies>
</plugin>

值得注意的是,此版本需要Java 8才能运行

创建测试时,请确保导入org.junit.jupiter.api.Test ,而不是org.junit.Test。此外,测试方法不再需要 public, package 级别的也可以。

3. What’s New

JUnit 5试图充分利用Java 8的新特性,特别是lambda表达式。

3.1 断言

断言已移至org.junit.jupiter.api.Assertions并已得到显着改进。如前所述,您现在可以在断言中使用lambdas:

1
2
3
4
5
6
7
@Test
void lambdaExpressions() {
assertTrue(Stream.of(1, 2, 3)
.stream()
.mapToInt(i -> i)
.sum() > 5, () -> "Sum should be greater than 5");
}

虽然上面的例子非常简单,但是对断言消息使用lambda表达式的一个优点是它被 lazy evaluate,如果消息构造很昂贵,这可以节省时间和资源。

现在还可以使用assertAll()对断言进行分组,该断言将使用MultipleFailuresError报告组内任何失败的断言:

1
2
3
4
5
6
7
8
9
@Test
void groupAssertions() {
int[] numbers = {0, 1, 2, 3, 4};
assertAll("numbers",
() -> assertEquals(numbers[0], 1),
() -> assertEquals(numbers[3], 3),
() -> assertEquals(numbers[4], 1)
);
}

这意味着现在制作更复杂的断言更安全,因为您将能够确定任何故障的确切位置。

3.2 断言

假设仅在满足某些条件时用于运行测试。这通常用于测试正常运行所需的外部条件,但这些条件与正在测试的内容无直接关系。

您可以使用assumeTrue()assumeFalse()assumeThat()声明一个假设

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
void trueAssumption() {
assumeTrue(5 > 1);
assertEquals(5 + 2, 7);
}

@Test
void falseAssumption() {
assumeFalse(5 < 1);
assertEquals(5 + 2, 7);
}

@Test
void assumptionThat() {
String someString = "Just a string";
assumingThat(
someString.equals("Just a string"),
() -> assertEquals(2 + 2, 4)
);
}

如果假设失败,则抛出TestAbortedException并简单地跳过测试,假设也支持lambda表达式。

3.3 异常

JUnit 5改进了对异常的支持。添加了一个assertThrows()方法,用于验证表达式是否抛出给定类型的表达式:

1
2
3
4
5
6
7
@Test
void shouldThrowException() {
Throwable exception = assertThrows(UnsupportedOperationException.class, () -> {
throw new UnsupportedOperationException("Not supported");
});
assertEquals(exception.getMessage(), "Not supported");
}

如示例所示,与JUnit 4相比,JUnit 5提供了对抛出异常的更多控制。最明显的含义是,现在可以轻松获取有关异常的任何信息,就像我们在示例中通过检查异常消息所做的那样。

3.4 嵌套测试

添加了嵌套测试,以允许开发人员表达不同测试组之间的复杂关系。语法非常简单 - 您只需要使用@Nested注释内部类。

JUnit文档提供了非常完成的示例,其中说明了可能的用途之一。

3.5 禁用测试

现在可以使用@Disabled注释禁用测试。

1
2
3
4
5
@Test
@Disabled
void disabledTest() {
assertTrue(false);
}

此测试不会运行。所述@Disabled注释可以应用于任一个测试用例或测试方法,相当于 JUnit4 中的@Ignore

3.6 标记

标签是JUnit 4中Categories的替代。标签可以与@Tag注释一起应用。这些允许开发人员分组和过滤测试。

1
2
3
4
5
6
7
8
9
@Tag("Test case")
public class TaggedTest {

@Test
@Tag("Method")
void testMethod() {
assertEquals(2+2, 4);
}
}

4. 结论

这篇文章快速概述了JUnit 5带来的变化。

值得注意的是,在编写本文时,只有Alpha版本可用,因此有些内容可能会在发布之前发生变化。