The following sample test generates the output as printed below.
Sample test:
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;
class OuterTest
{
@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 );
}
}
}
Output:
outerSetup
outerTest1
outerTearDown
outerSetup
outerTest2
outerTearDown
outerSetup
innerSetup
innerRepeatedTest
innerTearDown
outerTearDown
outerSetup
innerSetup
innerRepeatedTest
innerTearDown
outerTearDown
outerSetup
innerSetup
innerRepeatedTest
innerTearDown
outerTearDown
outerSetup
innerSetup
innerParameterizedTest - foo
innerTearDown
outerTearDown
outerSetup
innerSetup
innerParameterizedTest - bar
innerTearDown
outerTearDown
outerSetup
innerSetup
innerParameterizedTest - baz
innerTearDown
outerTearDown
outerSetup
innerSetup
innerTest1
innerTearDown
outerTearDown
outerSetup
innerSetup
innerTest2
innerTearDown
outerTearDown
For our use case we want to achieve, that the @BeforeEach
/@AfterEach
methods are only called before/after each test in class OuterTest
and before the first resp. after the last test in class InnerTest
, but not between the tests of the inner class.
So the desired output is the following:
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
I tried to change the behavior of the @BeforeEach
/@AfterEach
methods by implementing an extension, which implements an InvocationInterceptor
, but I failed to find out if a test class is the last test in the inner class, which would enable to decide, if the @BeforeEach
/@AfterEach
methods of the outer class should be called or not.
Does anyone know how to achieve this?
Thanks in advance!