第5章 教程
在本 Junit 教程中,我们将使用例子介绍 JUnit5 及其新功能的基本知识. 在 Java 世界中, JUnit 是用于实施对 Java 代码的单元测试的流行的框架之一. JUnit 主要有助于开发人员自行测试 JVM上的代码。
JUnit5 架构
联合平台
- 在 JVM 上启动测试框架
- 使用 TestEngine API 构建在 JUnit 平台上运行的测试框架
木星周日
- 用于编写测试的新编程模型和扩展模型的混合
- 添加新的 注释如
@BeforeEach
,@AfterEach
,@AfterAll
,@BeforeAll
等
青春 青春
- 支持在这个新平台上执行之前的 JUnit 版本 3 和 4 测试
依赖性 Maven
若要在项目中实施基于 JUnit5 的测试案例,请将以下依赖性添加到项目的 pom.xml 文件中:
- JUnit 5 图书馆
1<dependency>
2 <groupId>org.junit.jupiter</groupId>
3 <artifactId>junit-jupiter-engine</artifactId>
4 <version>5.1.1</version>
5 <scope>test</scope>
6</dependency>
7<dependency>
8 <groupId>org.junit.platform</groupId>
9 <artifactId>junit-platform-runner</artifactId>
10 <version> 1.1.1</version>
11 <scope>test</scope>
12</dependency>
- JUnit5 maven surefire 提供商可在 IDE 没有 JUnit5 支持的情况下执行单元测试(如果 IDE 支持,则不需要此点)
1<plugin>
2 <artifactId>maven-surefire-plugin</artifactId>
3 <version>2.19.1</version>
4 <dependencies>
5 <dependency>
6 <groupId>org.junit.platform</groupId>
7 <artifactId>junit-platform-surefire-provider</artifactId>
8 <version>1.0.2</version>
9 </dependency>
10 </dependencies>
11</plugin>
JUnit5新功能
它需要运行时的Java 8或更高版本,但仍然可以测试使用以前的Java版本编译的代码。
周日评论
以下是其中提供的一些常用的注释:
Annotation | Description |
---|---|
@Test | Denotes a test method |
@DisplayName | Declares a custom display name for the test class or test method |
@BeforeEach | Denotes that the annotated method should be executed before each test method |
@AfterEach | Denotes that the annotated method should be executed after each test method |
@BeforeAll | Denotes that the annotated method should be executed before all test methods |
@AfterAll | Denotes that the annotated method should be executed after all test methods |
@Disable | Used to disable a test class or test method |
@Nested | Denotes that the annotated class is a nested, non-static test class |
@Tag | Declare tags for filtering tests |
@ExtendWith | Register custom extensions |
1package com.journaldev;
2
3import org.junit.jupiter.api.AfterAll;
4import org.junit.jupiter.api.AfterEach;
5import org.junit.jupiter.api.BeforeAll;
6import org.junit.jupiter.api.BeforeEach;
7import org.junit.jupiter.api.Disabled;
8import org.junit.jupiter.api.DisplayName;
9import org.junit.jupiter.api.Test;
10
11public class JUnit5Sample1Test {
12
13 @BeforeAll
14 static void beforeAll() {
15 System.out.println("**--- Executed once before all test methods in this class ---**");
16 }
17
18 @BeforeEach
19 void beforeEach() {
20 System.out.println("**--- Executed before each test method in this class ---**");
21 }
22
23 @Test
24 void testMethod1() {
25 System.out.println("**--- Test method1 executed ---**");
26 }
27
28 @DisplayName("Test method2 with condition")
29 @Test
30 void testMethod2() {
31 System.out.println("**--- Test method2 executed ---**");
32 }
33
34 @Test
35 @Disabled("implementation pending")
36 void testMethod3() {
37 System.out.println("**--- Test method3 executed ---**");
38 }
39
40 @AfterEach
41 void afterEach() {
42 System.out.println("**--- Executed after each test method in this class ---**");
43 }
44
45 @AfterAll
46 static void afterAll() {
47 System.out.println("**--- Executed once after all test methods in this class ---**");
48 }
49
50}
We can run above JUnit test class in Eclipse -> Run As -> JUnit Test.
犹太人声明
每个测试方法必须使用声明对条件进行评估,以便测试可以继续执行。
Assertion | Description |
---|---|
assertEquals(expected, actual) | Fails when expected does not equal actual |
assertFalse(expression) | Fails when expression is not false |
assertNull(actual) | Fails when actual is not null |
assertNotNull(actual) | Fails when actual is null |
assertAll() | Group many assertions and every assertion is executed even if one or more of them fails |
assertTrue(expression) | Fails if expression is not true |
assertThrows() | Class to be tested is expected to throw an exception |
1@Test
2void testAssertEqual() {
3 assertEquals("ABC", "ABC");
4 assertEquals(20, 20, "optional assertion message");
5 assertEquals(2 + 2, 4);
6}
7
8@Test
9void testAssertFalse() {
10 assertFalse("FirstName".length() == 10);
11 assertFalse(10 > 20, "assertion message");
12}
13
14@Test
15void testAssertNull() {
16 String str1 = null;
17 String str2 = "abc";
18 assertNull(str1);
19 assertNotNull(str2);
20}
21
22@Test
23void testAssertAll() {
24 String str1 = "abc";
25 String str2 = "pqr";
26 String str3 = "xyz";
27 assertAll("numbers",
28 () -> assertEquals(str1,"abc"),
29 () -> assertEquals(str2,"pqr"),
30 () -> assertEquals(str3,"xyz")
31 );
32 //uncomment below code and understand each assert execution
33 /*assertAll("numbers",
34 () -> assertEquals(str1,"abc"),
35 () -> assertEquals(str2,"pqr1"),
36 () -> assertEquals(str3,"xyz1")
37 );*/
38}
39
40@Test
41void testAssertTrue() {
42 assertTrue("FirstName".startsWith("F"));
43 assertTrue(10 {
44 throw new IllegalArgumentException("Illegal Argument Exception occured");
45 });
46 assertEquals("Illegal Argument Exception occured", exception.getMessage());
47}
5 进口
它的测试类需要org.junit.jupiter.api.Test
导入声明,而不是org.junit.Test
。
1import org.junit.jupiter.api.Test;
第5章 假设
假设是org.junit.jupiter.api.Assumptions
类中的静态方法,它们只在满足指定的条件时执行测试,否则测试将被中断,而被中断的测试不会导致构建失败。
五、假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设: 假设:
1@Test
2void testAssumeTrue() {
3 boolean b = 'A' == 'A';
4 assumeTrue(b);
5 assertEquals("Hello", "Hello");
6}
7
8@Test
9@DisplayName("test executes only on Saturday")
10public void testAssumeTrueSaturday() {
11 LocalDateTime dt = LocalDateTime.now();
12 assumeTrue(dt.getDayOfWeek().getValue() == 6);
13 System.out.println("further code will execute only if above assumption holds true");
14}
15
16@Test
17void testAssumeFalse() {
18 boolean b = 'A' != 'A';
19 assumeFalse(b);
20 assertEquals("Hello", "Hello");
21}
22
23@Test
24void testAssumeFalseEnvProp() {
25 System.setProperty("env", "prod");
26 assumeFalse("dev".equals(System.getProperty("env")));
27 System.out.println("further code will execute only if above assumption hold");
28}
29
30@Test
31void testAssumingThat() {
32 System.setProperty("env", "test");
33 assumingThat("test".equals(System.getProperty("env")),
34 () -> {
35 assertEquals(10, 10);
36 System.out.println("perform below assertions only on the test env");
37 });
38
39 assertEquals(20, 20);
40 System.out.println("perform below assertions on all env");
41}
JUnit Nested 测试班级
嵌入式测试允许创建嵌入式类,并执行其所有测试方法. 内部类必须非静态. 只需用 @Nested 注明内部类,将执行其中的所有测试方法。
1@BeforeAll
2static void beforeAll() {
3 System.out.println("**--- JUnit5Sample4Test :: beforeAll :: Executed once before all test methods ---**");
4}
5
6@BeforeEach
7void beforeEach() {
8 System.out.println("**--- JUnit5Sample4Test :: beforeEach :: Executed before each test method ---**");
9}
10
11@AfterEach
12void afterEach() {
13 System.out.println("**--- JUnit5Sample4Test :: afterEach :: Executed after each test method ---**");
14}
15
16@AfterAll
17static void afterAll() {
18 System.out.println("**--- JUnit5Sample4Test :: afterAll :: Executed after all test method ---**");
19}
20
21 @Nested
22 class InnerClass {
23
24 @BeforeEach
25 void beforeEach() {
26 System.out.println("**--- InnerClass :: beforeEach :: Executed before each test method ---**");
27 }
28
29 @AfterEach
30 void afterEach() {
31 System.out.println("**--- InnerClass :: afterEach :: Executed after each test method ---**");
32 }
33
34 @Test
35 void testMethod1() {
36 System.out.println("**--- InnerClass :: testMethod1 :: Executed test method1 ---**");
37 }
38
39 @Nested
40 class InnerMostClass {
41
42 @BeforeEach
43 void beforeEach() {
44 System.out.println("**--- InnerMostClass :: beforeEach :: Executed before each test method ---**");
45 }
46
47 @AfterEach
48 void afterEach() {
49 System.out.println("**--- InnerMostClass :: afterEach :: Executed after each test method ---**");
50 }
51
52 @Test
53 void testMethod2() {
54 System.out.println("**--- InnerMostClass :: testMethod2 :: Executed test method2 ---**");
55 }
56 }
57 }
JUnit测试例外
在某些情况下,方法有望在特定条件下投出例外. assertThrows 如果该方法没有投出指定的例外,则测试将失败。
1Throwable exception = assertThrows(IllegalArgumentException.class, () -> {
2 throw new IllegalArgumentException("Illegal Argument Exception occured");
3});
4assertEquals("Illegal Argument Exception occured", exception.getMessage());
JUnit 测试执行
单元测试可以以多种方式进行,其中两种方式如下:
- 使用 Eclipse IDE Oxygen.3a(4.7.3a) 发布并打开测试文件来执行. 右键单击文件并选择选项运行 随后由 JUnit Test
- 在 Windows 命令提示 上使用 mvn test 命令
摘要
我们通过一些例子探索了 JUnit5 及其新功能,我们还研究了如何使用 JUnit 注释、声明、假设、例外,并撰写嵌入式测试类。
您可以从我们的 GitHub 存储库下载完整的示例项目。