JUnit5 教程

第5章 教程

在本 Junit 教程中,我们将使用例子介绍 JUnit5 及其新功能的基本知识. 在 Java 世界中, JUnit 是用于实施对 Java 代码的单元测试的流行的框架之一. JUnit 主要有助于开发人员自行测试 JVM上的代码。

JUnit5 架构

junit5 architecture

联合平台

  • 在 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版本编译的代码。

周日评论

以下是其中提供的一些常用的注释:

AnnotationDescription
@TestDenotes a test method
@DisplayNameDeclares a custom display name for the test class or test method
@BeforeEachDenotes that the annotated method should be executed before each test method
@AfterEachDenotes that the annotated method should be executed after each test method
@BeforeAllDenotes that the annotated method should be executed before all test methods
@AfterAllDenotes that the annotated method should be executed after all test methods
@DisableUsed to disable a test class or test method
@NestedDenotes that the annotated class is a nested, non-static test class
@TagDeclare tags for filtering tests
@ExtendWithRegister 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. Junit 5 tutorial, eclipse run junit test

犹太人声明

每个测试方法必须使用声明对条件进行评估,以便测试可以继续执行。

AssertionDescription
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 存储库下载完整的示例项目。

Published At
Categories with 技术
Tagged with
comments powered by Disqus