JUnit 5嵌套测试

时间:2020-02-23 14:35:24  来源:igfitidea点击:

JUnit Jupiter的@Nested批注可用于标记要包含在测试用例中的嵌套类。
执行JUnit测试时,不会扫描嵌套类的测试方法。
我们可以使用@Nested批注明确标记要扫描的测试用例。

JUnit 5嵌套测试

JUnit嵌套测试类应该是非静态的。
我们来看一个简单的JUnit 5嵌套测试类示例。

package com.theitroad.nested;

import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

public class NestedTestSimpleExample {

	@Test
	void test() {
		System.out.println("Outer Class Test");
	}
	
	@Nested
	class InnerClass {
		
		@Test
		void test() {
			System.out.println("Inner Class Test");
		}
	}
}

下图显示了Eclipse的JUnit执行报告。

如果我们从内部类中删除@Nested批注,则其中的测试将不会执行。

JUnit嵌套测试回调方法

嵌套测试类可以具有自己的@BeforeEach和@AfterEach方法。
但是,如果外部类@ BeforeEach@ AfterEach方法也将为嵌套类测试执行。
让我们扩展示例以确认这种行为。

package com.theitroad.nested;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

public class NestedTestSimpleExample {

	@BeforeAll
	static void setUpBeforeClass() throws Exception {
		System.out.println("@BeforeAll - Outer Class");
	}

	@AfterAll
	static void tearDownAfterClass() throws Exception {
		System.out.println("@AfterAll - Outer Class");
	}

	@BeforeEach
	void setUp() throws Exception {
		System.out.println("@BeforeEach - Outer Class");
	}

	@AfterEach
	void tearDown() throws Exception {
		System.out.println("@AfterEach - Outer Class");
	}
	
	@Test
	void test() {
		System.out.println("Outer Class Test");
	}
	
	@Nested
	class InnerClass {
		@BeforeEach
		void setUp() throws Exception {
			System.out.println("@BeforeEach - Inner Class");
		}

		@AfterEach
		void tearDown() throws Exception {
			System.out.println("@AfterEach - Inner Class");
		}
		
		@Test
		void test() {
			System.out.println("Inner Class Test");
		}
	}
}

JUnit测试执行的控制台输出清楚地确认了此行为。

@BeforeAll - Outer Class

@BeforeEach - Outer Class
Outer Class Test
@AfterEach - Outer Class

@BeforeEach - Outer Class
@BeforeEach - Inner Class
Inner Class Test
@AfterEach - Inner Class
@AfterEach - Outer Class

@AfterAll - Outer Class

如果要在嵌套测试类中使用@BeforeAll和@AfterAll方法,则必须将其生命周期行为显式设置为"每个类"。
JUnit测试用例的默认行为是"按方法"。

package com.theitroad.nested;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;

class NestedExampleTest {

	@BeforeAll
	static void setUpBeforeClass() throws Exception {
		System.out.println("@BeforeAll - Outer Class");
	}

	@AfterAll
	static void tearDownAfterClass() throws Exception {
		System.out.println("@AfterAll - Outer Class");
	}

	@BeforeEach
	void setUp() throws Exception {
		System.out.println("@BeforeEach - Outer Class");
	}

	@AfterEach
	void tearDown() throws Exception {
		System.out.println("@AfterEach - Outer Class");
	}

	@Test
	void outer_test() {
		System.out.println("Outer Class test method");
	}

	@Nested
	@TestInstance(Lifecycle.PER_CLASS)
	class InnerClass {
		@BeforeAll
		void setUpBeforeClassInner() throws Exception {
			System.out.println("@BeforeAll - Inner Class");
		}

		@AfterAll
		void tearDownAfterClassInner() throws Exception {
			System.out.println("@AfterAll - Inner Class");
		}

		@BeforeEach
		void setUp() throws Exception {
			System.out.println("@BeforeEach - Inner Class");
		}

		@AfterEach
		void tearDown() throws Exception {
			System.out.println("@AfterEach - Inner Class");
		}

		@Test
		void inner_test() {
			System.out.println("Inner Class test method");
		}
	}
}

这是JUnit测试的控制台输出:

@BeforeAll - Outer Class

@BeforeEach - Outer Class
Outer Class test method
@AfterEach - Outer Class

@BeforeAll - Inner Class

@BeforeEach - Outer Class
@BeforeEach - Inner Class
Inner Class test method
@AfterEach - Inner Class
@AfterEach - Outer Class

@AfterAll - Inner Class
@AfterAll - Outer Class