Consider the following Kotlin test class using JUnit 5 lifecycle annotations. What will be printed when running all tests?
import org.junit.jupiter.api.* @TestInstance(TestInstance.Lifecycle.PER_CLASS) class LifecycleTest { init { println("Init block") } @BeforeAll fun beforeAll() { println("BeforeAll") } @BeforeEach fun beforeEach() { println("BeforeEach") } @Test fun testOne() { println("TestOne") } @Test fun testTwo() { println("TestTwo") } @AfterEach fun afterEach() { println("AfterEach") } @AfterAll fun afterAll() { println("AfterAll") } }
Remember that with @TestInstance(TestInstance.Lifecycle.PER_CLASS), the test class is instantiated once, so the init block runs once.
The init block runs once when the class instance is created. @BeforeAll runs once before all tests. @BeforeEach and @AfterEach run before and after each test respectively. @AfterAll runs once after all tests.
Given this Kotlin test class without @TestInstance(TestInstance.Lifecycle.PER_CLASS), what will happen when running the tests?
import org.junit.jupiter.api.* class StaticBeforeAllTest { @BeforeAll fun setup() { println("Setup") } @Test fun testA() { println("TestA") } }
In JUnit 5, @BeforeAll methods must be static unless the test class uses @TestInstance(PER_CLASS).
Without @TestInstance(PER_CLASS), JUnit 5 requires @BeforeAll methods to be static. Otherwise, it throws a runtime error.
Look at this Kotlin test class. The @AfterEach method is not running after tests. What is the reason?
import org.junit.jupiter.api.* @TestInstance(TestInstance.Lifecycle.PER_CLASS) class AfterEachIssue { @AfterEach fun tearDown() { println("TearDown") } @Test fun testOne() { println("TestOne") } @Test fun testTwo() { println("TestTwo") } fun afterEach() { println("This is not annotated") } }
Check which methods have the @AfterEach annotation and their visibility.
The method 'tearDown' is annotated with @AfterEach and will run after each test. The other method 'afterEach' is not annotated, so it won't run automatically.
Given this Kotlin test class with nested classes and lifecycle annotations, what is the output when running all tests?
import org.junit.jupiter.api.* @TestInstance(TestInstance.Lifecycle.PER_CLASS) class NestedLifecycleTest { @BeforeAll fun beforeAll() { println("Outer BeforeAll") } @BeforeEach fun beforeEach() { println("Outer BeforeEach") } @Test fun outerTest() { println("Outer Test") } @Nested inner class Inner { @BeforeAll fun innerBeforeAll() { println("Inner BeforeAll") } @BeforeEach fun innerBeforeEach() { println("Inner BeforeEach") } @Test fun innerTest() { println("Inner Test") } @AfterEach fun innerAfterEach() { println("Inner AfterEach") } @AfterAll fun innerAfterAll() { println("Inner AfterAll") } } @AfterEach fun afterEach() { println("Outer AfterEach") } @AfterAll fun afterAll() { println("Outer AfterAll") } }
Remember that @BeforeAll and @AfterAll in nested classes run once per nested class instance.
The outer class @BeforeAll runs once first. Then the outer test runs with its @BeforeEach and @AfterEach. The nested class @BeforeAll runs once before its tests. Each nested test runs with both outer and inner @BeforeEach and @AfterEach. Finally, nested @AfterAll and outer @AfterAll run.
Which statement best describes the effect of annotating a Kotlin JUnit 5 test class with @TestInstance(TestInstance.Lifecycle.PER_CLASS)?
Think about how many times the test class is created and how that affects instance variables.
With @TestInstance(TestInstance.Lifecycle.PER_CLASS), JUnit creates one instance of the test class and reuses it for all tests. This allows instance variables to keep state between tests and allows non-static lifecycle methods like @BeforeAll.