0
0
Kotlinprogramming~20 mins

Test fixtures and lifecycle in Kotlin - Practice Problems & Coding Challenges

Choose your learning style9 modes available
Challenge - 5 Problems
🎖️
JUnit 5 Lifecycle Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
Predict Output
intermediate
2:00remaining
What is the output of this JUnit 5 test lifecycle code?

Consider the following Kotlin test class using JUnit 5 lifecycle annotations. What will be printed when running all tests?

Kotlin
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")
    }
}
A
BeforeAll
BeforeEach
TestOne
AfterEach
BeforeEach
TestTwo
AfterEach
AfterAll
B
Init block
BeforeAll
BeforeEach
TestOne
AfterEach
BeforeEach
TestTwo
AfterEach
AfterAll
C
Init block
BeforeEach
TestOne
AfterEach
BeforeEach
TestTwo
AfterEach
D
Init block
BeforeAll
BeforeEach
TestOne
BeforeEach
TestTwo
AfterEach
AfterAll
Attempts:
2 left
💡 Hint

Remember that with @TestInstance(TestInstance.Lifecycle.PER_CLASS), the test class is instantiated once, so the init block runs once.

Predict Output
intermediate
2:00remaining
What happens if @BeforeAll is not static in JUnit 5 without @TestInstance(PER_CLASS)?

Given this Kotlin test class without @TestInstance(TestInstance.Lifecycle.PER_CLASS), what will happen when running the tests?

Kotlin
import org.junit.jupiter.api.*

class StaticBeforeAllTest {

    @BeforeAll
    fun setup() {
        println("Setup")
    }

    @Test
    fun testA() {
        println("TestA")
    }
}
A
Tests run successfully and print:
Setup
TestA
BTests run but 'setup' method is never called
CRuntime error: 'setup' method must be static or the test class must be annotated with @TestInstance(PER_CLASS)
DCompile error: Missing static modifier on 'setup' method
Attempts:
2 left
💡 Hint

In JUnit 5, @BeforeAll methods must be static unless the test class uses @TestInstance(PER_CLASS).

🔧 Debug
advanced
2:00remaining
Why does this @AfterEach method not run after tests?

Look at this Kotlin test class. The @AfterEach method is not running after tests. What is the reason?

Kotlin
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")
    }
}
AThe @AfterEach method 'tearDown' is correctly annotated and will run after each test
BThe @AfterEach annotation is missing on the method that prints 'This is not annotated'
CThe method named 'tearDown' is private by default and not accessible
DJUnit 5 requires @AfterEach methods to be static, so 'tearDown' is ignored
Attempts:
2 left
💡 Hint

Check which methods have the @AfterEach annotation and their visibility.

Predict Output
advanced
2:30remaining
What is the output order with nested @Nested test classes and lifecycle methods?

Given this Kotlin test class with nested classes and lifecycle annotations, what is the output when running all tests?

Kotlin
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")
    }
}
A
Outer BeforeAll
Outer BeforeEach
Outer Test
Outer AfterEach
Inner BeforeAll
Outer BeforeEach
Inner BeforeEach
Inner Test
Inner AfterEach
Outer AfterEach
Inner AfterAll
Outer AfterAll
B
Outer BeforeAll
Outer BeforeEach
Outer Test
Outer AfterEach
Outer BeforeEach
Inner BeforeEach
Inner Test
Inner AfterEach
Outer AfterEach
Outer AfterAll
C
Outer BeforeAll
Outer BeforeEach
Outer Test
Outer AfterEach
Inner BeforeAll
Inner BeforeEach
Inner Test
Inner AfterEach
Inner AfterAll
Outer AfterAll
D
Outer BeforeAll
Outer BeforeEach
Outer Test
Outer AfterEach
Inner BeforeEach
Inner Test
Inner AfterEach
Outer AfterEach
Outer AfterAll
Attempts:
2 left
💡 Hint

Remember that @BeforeAll and @AfterAll in nested classes run once per nested class instance.

🧠 Conceptual
expert
2:00remaining
How does @TestInstance(TestInstance.Lifecycle.PER_CLASS) affect test fixture lifecycle?

Which statement best describes the effect of annotating a Kotlin JUnit 5 test class with @TestInstance(TestInstance.Lifecycle.PER_CLASS)?

AJUnit requires all lifecycle methods to be static and disables instance methods for setup and teardown.
BJUnit creates a new instance of the test class for each test method, so instance variables are reset each time.
CJUnit runs all tests in parallel threads sharing the same test class instance without synchronization.
DJUnit creates a single instance of the test class for all test methods, allowing instance variables to be shared across tests.
Attempts:
2 left
💡 Hint

Think about how many times the test class is created and how that affects instance variables.