Home Junit 5 Junit 5 test instance lifecycle with examples

Junit 5 test instance lifecycle with examples

1. Junit 5 test instance lifecycle

JUnit creates a new instance of each test class before executing each test method. The default behavior of Junit 5 test instance lifecycle is “per-method”. Junit 5 supports two instance lifecycle modes.

  1. Lifecycle per-method.
  2. Lifecycle per-class.

You can set the instance lifecycle mode for the tests by annotating with @TestInstance annotation to the test class.

2. Lifecycle per-method mode

This is default behavior for all versions of Junit. When using this mode, a new test instance will be created for each test method, test factory method, or test template method.

@TestInstance(Lifecycle.PER_METHOD)
public class MathUtilTest {
	
	private int result = 5;
	
	@Test
	void test_Add() {
		result = MathUtil.add(result, 5);
		System.out.println("test_Add(5,5) => "+result);
		assertEquals(10, result);
	}
	
	@Test
	void test_Multiply() {
		result = MathUtil.multiple(result, 5);
		System.out.println("test_Multiply(5,5) => "+result);
		assertEquals(25, result);
	}

	@Test
	void test_Devide() {
		result = MathUtil.devide(result, 5);
		System.out.println("test_Devide(5,5) => "+result);
		assertEquals(1, result);
	}	
}

Output :

test_Devide(5,5) => 1
test_Add(5,5) => 10
test_Multiply(5,5) => 25

3. Lifecycle per-class mode

3.1. When using this mode, a new test instance will be created once per test class. In this mode shared test instance state between test methods in a given test class as well as between non-static @BeforeAll and @AfterAll

@TestInstance(Lifecycle.PER_CLASS)
public class MathUtilTest {
	
	private int result = 5;
	
	@Test
	void test_Add() {
		result = MathUtil.add(result, 5);
		System.out.println("test_Add(5,5) => "+result);
		assertEquals(10, result);
	}
	
	@Test
	void test_Multiply() {
		result = MathUtil.multiple(result, 5);
		System.out.println("test_Multiply(5,5) => "+result);
		assertEquals(25, result);
	}

	@Test
	void test_Devide() {
		result = MathUtil.devide(result, 5);
		System.out.println("test_Devide(5,5) => "+result);
		assertEquals(1, result);
	}	
}

Output :

test_Devide(5,5) => 1
test_Add(5,5) => 6
test_Multiply(5,5) => 30

3.2. The Default mode of test instance lifecycle is PER_METHOD, if you are not set test instance lifecycle mode as Lifecycle.PER_CLASS, @BeforeAll and @AfterAll call back methods should be static, otherwise you will get compile time error. If your lifecycle mode is Lifecycle.PER_CLASS you can make @BeforeAll and @AfterAll methods as non-static.

@TestInstance(Lifecycle.PER_CLASS)
public class Junit5_TestInstance_Lifecycle_Test {
	
	@BeforeAll
	void beforeAll() {
		// here common setup for all tests
		System.out.println("--- Before starting tests --- ");
	}
	
	@BeforeEach
	void beforeEach(TestInfo testInfo) {
		// here initialize setup for each test
		System.out.println("Before Strat test >>>> "+testInfo.getTestMethod().get().getName());
	}

	@Test
	void test_Add() {
		System.out.println("MathUtil.add(5, 5) => "+MathUtil.add(5, 5));
		assertEquals(10, MathUtil.add(5, 5));
	}
	
	@Test
	void test_Multiply() {

		System.out.println("MathUtil.multiple(5, 5) => "+MathUtil.multiple(5, 5));
		assertEquals(25, MathUtil.multiple(5, 5));
	}

	
	@AfterEach
	void afetrEach(TestInfo testInfo) {
		// here cleanup setup after each test completes
		System.out.println("After complete test >>>> "+testInfo.getTestMethod().get().getName());
	}
	
	@AfterAll
	void afetrAll() {
		// here cleanup setup after all tests completes
		System.out.println("--- After tests completed ---");
	}	
}

Output :

--- Before starting tests --- 
Before Strat test >>>> test_Add
MathUtil.add(5, 5) => 10
After complete test >>>> test_Add
Before Strat test >>>> test_Multiply
MathUtil.multiple(5, 5) => 25
After complete test >>>> test_Multiply
--- After tests completed ---

3.3. By default Junit 5 nested test classes not allow to write @BeforeAll and @AfterAll methods, you can write them in nested classes only if test lifecycle mode is Lifecycle.PER_CLASS and they should be non-static.

public class Junit5_NestedTests_Test {

	@Test
	void test1() {
		System.out.println("=> test1()");
	}

	@Nested
	@TestInstance(Lifecycle.PER_CLASS)
	class TestA {

		@BeforeAll
		void testA_BeforeAll() {
			System.out.println("=> testA_BeforeAll()");
		}

		@Test
		void testA_test1() {
			System.out.println("=> testA_test1()");
		}
	}
}

Output :

=> test1()
=> testA_BeforeAll()
=> testA_test1()

3.4. You can declare @BeforeAll and @AfterAll on interface methods.

@TestInstance(Lifecycle.PER_CLASS)
public interface IBaseTest {

	@BeforeAll
	default void beforeAll() {
		// here common setup for all tests
		System.out.println("--- Before starting tests --- ");
	}
	
	@AfterAll
	default void afetrAll() {
		// here cleanup setup after all tests completes
		System.out.println("--- After tests completed ---");
	}	
}
public class IntsanceLifecycleTest implements IBaseTest {
	
	private int result = 5;
	
	@Test
	void test_Add() {
		result = MathUtil.add(result, 5);
		System.out.println("test_Add(5,5) => "+result);
		assertEquals(10, result);
	}
	
	@Test
	void test_Multiply() {
		result = MathUtil.multiple(result, 5);
		System.out.println("test_Multiply(5,5) => "+result);
		assertEquals(25, result);
	}

	@Test
	void test_Devide() {
		result = MathUtil.devide(result, 5);
		System.out.println("test_Devide(5,5) => "+result);
		assertEquals(1, result);
	}	
}

Output :

--- Before starting tests --- 
test_Devide(5,5) => 1
test_Add(5,5) => 6
test_Multiply(5,5) => 30
--- After tests completed ---

4. Globally change Default Test Instance Lifecycle

To change the default test instance lifecycle mode, set the junit.jupiter.testinstance.lifecycle.default configuration parameter to the name of an enum constant defined in TestInstance.Lifecycle, ignoring case. 

Create a file named junit-platform.properties in the root of the class path in src/test/resources.

  1. -Djunit.jupiter.testinstance.lifecycle.default=per_class – to set test instance lifecycle mode to per_class
  2. -Djunit.jupiter.testinstance.lifecycle.default=per_method – to set test instance lifecycle mode to per_method (actually no need to set this, because it’s default behavior)

5. Conclusion

In this article we have covered Junit 5 test instance lifecycle and instance lifecycle modes with several examples.

References

  1. Junit 5 document
Satish Varma
Satish Varmahttps://javabydeveloper.com
Satish is post graduated in master of computer applications and experienced software engineer with focus on Spring, JPA, REST, TDD and web development. Follow him on LinkedIn or Twitter or Facebook

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Stay in Touch

Categories