以下示例测试生成如下打印的输出。
样品测试:
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
public class OuterTest extends ParentTest implements TestInterface1, TestInterface2
{
@BeforeEach
void outerSetup()
{
System.out.println( " outerSetup" );
}
@AfterEach
void outerTearDown()
{
System.out.println( " outerTearDown" );
}
@Test
void outerTest1()
{
System.out.println( " outerTest1" );
}
@Test
void outerTest2()
{
System.out.println( " outerTest2" );
}
@Nested
class InnerTest
{
@BeforeEach
void innerSetup()
{
System.out.println( " innerSetup" );
}
@AfterEach
void innerTearDown()
{
System.out.println( " innerTearDown" );
}
@Test
void innerTest1()
{
System.out.println( " innerTest1" );
}
@Test
void innerTest2()
{
System.out.println( " innerTest2" );
}
@RepeatedTest(3)
void innerRepeatedTest()
{
System.out.println( " innerRepeatedTest" );
}
@ParameterizedTest
@ValueSource(strings = { "foo", "bar", "baz" })
void innerParameterizedTest( final String input )
{
System.out.println( " innerParameterizedTest - " + input );
}
}
}
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
public class ParentTest
{
@BeforeEach
void parentSetup()
{
System.out.println( "parentSetup" );
}
@AfterEach
void parentTearDown()
{
System.out.println( "parentTearDown" );
}
}
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
public interface TestInterface1
{
@BeforeEach
default void interface1Setup()
{
System.out.println( "interface1Setup" );
}
@AfterEach
default void interface1TearDown()
{
System.out.println( "interface1TearDown" );
}
}
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
public interface TestInterface2
{
@BeforeEach
default void interface2Setup()
{
System.out.println( "interface2Setup" );
}
@AfterEach
default void interface2TearDown()
{
System.out.println( "interface2TearDown" );
}
}
输出:
parentSetup
interface1Setup
interface2Setup
outerSetup
outerTest1
outerTearDown
interface1TearDown
interface2TearDown
parentTearDown
parentSetup
interface1Setup
interface2Setup
outerSetup
outerTest2
outerTearDown
interface1TearDown
interface2TearDown
parentTearDown
parentSetup
interface1Setup
interface2Setup
outerSetup
innerSetup
innerRepeatedTest
innerTearDown
outerTearDown
interface1TearDown
interface2TearDown
parentTearDown
parentSetup
interface1Setup
interface2Setup
outerSetup
innerSetup
innerRepeatedTest
innerTearDown
outerTearDown
interface1TearDown
interface2TearDown
parentTearDown
parentSetup
interface1Setup
interface2Setup
outerSetup
innerSetup
innerRepeatedTest
innerTearDown
outerTearDown
interface1TearDown
interface2TearDown
parentTearDown
parentSetup
interface1Setup
interface2Setup
outerSetup
innerSetup
innerParameterizedTest - foo
innerTearDown
outerTearDown
interface1TearDown
interface2TearDown
parentTearDown
parentSetup
interface1Setup
interface2Setup
outerSetup
innerSetup
innerParameterizedTest - bar
innerTearDown
outerTearDown
interface1TearDown
interface2TearDown
parentTearDown
parentSetup
interface1Setup
interface2Setup
outerSetup
innerSetup
innerParameterizedTest - baz
innerTearDown
outerTearDown
interface1TearDown
interface2TearDown
parentTearDown
parentSetup
interface1Setup
interface2Setup
outerSetup
innerSetup
innerTest1
innerTearDown
outerTearDown
interface1TearDown
interface2TearDown
parentTearDown
parentSetup
interface1Setup
interface2Setup
outerSetup
innerSetup
innerTest2
innerTearDown
outerTearDown
interface1TearDown
interface2TearDown
parentTearDown
对于我们的用例,我们希望实现,
@BeforeEach
/@AfterEach
方法仅在类OuterTest
中的每个测试之前/之后调用,以及在第一个之前调用。 在类中的最后一个测试之后InnerTest
,但不在内部类的测试之间。
所以期望的输出如下:
parentSetup
interface1Setup
interface2Setup
outerSetup
outerTest1
outerTearDown
interface1TearDown
interface2TearDown
parentTearDown
parentSetup
interface1Setup
interface2Setup
outerSetup
outerTest2
outerTearDown
interface1TearDown
interface2TearDown
parentTearDown
parentSetup
interface1Setup
interface2Setup
outerSetup
innerSetup
innerRepeatedTest
innerTearDown
innerSetup
innerRepeatedTest
innerTearDown
innerSetup
innerRepeatedTest
innerTearDown
innerSetup
innerParameterizedTest - foo
innerTearDown
innerSetup
innerParameterizedTest - bar
innerTearDown
innerSetup
innerParameterizedTest - baz
innerTearDown
innerSetup
innerTest1
innerTearDown
innerSetup
innerTest2
innerTearDown
outerTearDown
interface1TearDown
interface2TearDown
parentTearDown
我尝试通过实现扩展来更改
@BeforeEach
/@AfterEach
方法的行为,该扩展实现了 InvocationInterceptor
,但我无法确定测试类是否是内部类中的最后一个测试,这将导致能够决定是否应该调用外部类的 @BeforeEach
/@AfterEach
方法。
有谁知道如何实现这一目标?
提前致谢!
如果您能够提取实际的外部设置和拆卸方法,则可以为外部测试引入第二个
@Nested
类,并使用 @BeforeAll
和 @AfterAll
调用外部设置/拆卸一次:
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.RepeatedTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
class OuterTest {
void actualOuterSetUp() {
System.out.println("outerSetUp");
}
void actualOuterTearDown() {
System.out.println("outerTearDown");
}
@Nested
class InnerTestA {
@BeforeEach
void outerSetUp() {
actualOuterSetUp();
}
@AfterEach
void outerTearDown() {
actualOuterTearDown();
}
@Test
void outerTest1() {
System.out.println(" outerTest1");
}
@Test
void outerTest2() {
System.out.println(" outerTest2");
}
}
@Nested
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class InnerTestB {
@BeforeAll
void outerSetUp() {
actualOuterSetUp();
}
@AfterAll
void outerTearDown() {
actualOuterTearDown();
}
@BeforeEach
void innerSetUp() {
System.out.println(" innerSetUp");
}
@AfterEach
void innerTearDown() {
System.out.println(" innerTearDown");
}
@Test
void innerTest1() {
System.out.println(" innerTest1");
}
@Test
void innerTest2() {
System.out.println(" innerTest2");
}
@RepeatedTest(3)
void innerRepeatedTest() {
System.out.println(" innerRepeatedTest");
}
@ParameterizedTest
@ValueSource(strings = {"foo", "bar", "baz"})
void innerParameterizedTest(final String input) {
System.out.println(" innerParameterizedTest - " + input);
}
}
}
输出(嵌套类的顺序可能因系统而异):
outerSetUp
outerTest1
outerTearDown
outerSetUp
outerTest2
outerTearDown
outerSetUp
innerSetUp
innerRepeatedTest
innerTearDown
innerSetUp
innerRepeatedTest
innerTearDown
innerSetUp
innerRepeatedTest
innerTearDown
innerSetUp
innerParameterizedTest - foo
innerTearDown
innerSetUp
innerParameterizedTest - bar
innerTearDown
innerSetUp
innerParameterizedTest - baz
innerTearDown
innerSetUp
innerTest1
innerTearDown
innerSetUp
innerTest2
innerTearDown
outerTearDown
如果您使用的是 Java 16+,您还可以省略
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
并使用 static
代替。