Bird
Raised Fist0
JUnittesting~20 mins

Why lifecycle hooks manage setup and teardown in JUnit - Challenge Your Understanding

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Lifecycle Hook Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
🧠 Conceptual
intermediate
2:00remaining
Purpose of @BeforeEach in JUnit
In JUnit testing, what is the main purpose of the @BeforeEach lifecycle hook?
ATo run code once before all tests in the class
BTo run code before each individual test method
CTo run code after each test method
DTo clean up resources after all tests finish
Attempts:
2 left
💡 Hint
Think about preparing the environment fresh for every test.
🧠 Conceptual
intermediate
2:00remaining
Role of @AfterAll in JUnit
What is the role of the @AfterAll lifecycle hook in JUnit testing?
ATo initialize resources before any tests run
BTo run cleanup code after each test method
CTo run code before each test method
DTo run cleanup code once after all tests in the class have run
Attempts:
2 left
💡 Hint
Think about releasing shared resources after all tests finish.
❓ Predict Output
advanced
2:30remaining
Output of JUnit lifecycle hooks order
Given the following JUnit test class, what is the order of printed output when running all tests?
JUnit
import org.junit.jupiter.api.*;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class SampleTest {

    @BeforeAll
    void beforeAll() {
        System.out.println("BeforeAll");
    }

    @BeforeEach
    void beforeEach() {
        System.out.println("BeforeEach");
    }

    @Test
    void testOne() {
        System.out.println("TestOne");
    }

    @Test
    void testTwo() {
        System.out.println("TestTwo");
    }

    @AfterEach
    void afterEach() {
        System.out.println("AfterEach");
    }

    @AfterAll
    void afterAll() {
        System.out.println("AfterAll");
    }
}
ABeforeAll, BeforeEach, TestOne, AfterEach, BeforeEach, TestTwo, AfterEach, AfterAll
BBeforeEach, BeforeAll, TestOne, AfterEach, BeforeEach, TestTwo, AfterEach, AfterAll
CBeforeAll, TestOne, BeforeEach, AfterEach, TestTwo, BeforeEach, AfterEach, AfterAll
DBeforeAll, BeforeEach, TestOne, BeforeEach, TestTwo, AfterEach, AfterEach, AfterAll
Attempts:
2 left
💡 Hint
Remember the order: BeforeAll once, BeforeEach before each test, AfterEach after each test, AfterAll once.
❓ assertion
advanced
2:00remaining
Correct assertion for resource cleanup in @AfterEach
Which assertion correctly verifies that a resource is closed after each test using @AfterEach in JUnit?
JUnit
private Resource resource;

@BeforeEach
void setup() {
    resource = new Resource();
}

@AfterEach
void cleanup() {
    resource.close();
}
AassertEquals(null, resource);
BassertNull(resource);
CassertTrue(resource.isClosed());
DassertFalse(resource.isClosed());
Attempts:
2 left
💡 Hint
Check if the resource reports it is closed after cleanup.
🔧 Debug
expert
3:00remaining
Identify the problem with lifecycle hooks causing test interference
Consider this JUnit test class where tests sometimes fail due to shared state. What is the main issue causing this?
JUnit
import static org.junit.jupiter.api.Assertions.*;

public class SharedStateTest {
    private static int counter = 0;

    @BeforeAll
    static void init() {
        counter = 0;
    }

    @Test
    void testIncrement() {
        counter++;
        assertTrue(counter > 0);
    }

    @Test
    void testReset() {
        counter = 0;
        assertEquals(0, counter);
    }
}
AUsing static variable counter causes shared state between tests leading to interference
BLifecycle hooks are not annotated with @BeforeEach causing setup failure
CIncorrect assertion in testIncrement causes failure
DMissing @AfterEach to reset counter after each test
Attempts:
2 left
💡 Hint
Think about how static variables behave across tests.

Practice

(1/5)
1. Why do we use lifecycle hooks like @BeforeEach and @AfterEach in JUnit tests?
easy
A. To write test cases faster by skipping assertions
B. To run setup and cleanup code before and after each test automatically
C. To make tests run in parallel
D. To generate test reports automatically

Solution

  1. Step 1: Understand lifecycle hooks purpose

    Lifecycle hooks like @BeforeEach and @AfterEach run code before and after each test method to prepare and clean up the test environment.
  2. Step 2: Identify correct use case

    This avoids repeating setup and teardown code inside every test, keeping tests clean and consistent.
  3. Final Answer:

    To run setup and cleanup code before and after each test automatically -> Option B
  4. Quick Check:

    Lifecycle hooks = setup/teardown automation [OK]
Hint: Lifecycle hooks automate setup and cleanup around tests [OK]
Common Mistakes:
  • Thinking lifecycle hooks skip assertions
  • Confusing lifecycle hooks with parallel test execution
  • Assuming lifecycle hooks generate reports
2. Which of the following is the correct syntax to run a method once before all tests in a JUnit 5 test class?
easy
A. @BeforeEach public void setup() {}
B. @AfterAll public void finish() {}
C. @BeforeAll public static void init() {}
D. @AfterEach public void cleanup() {}

Solution

  1. Step 1: Identify the annotation for running once before all tests

    The @BeforeAll annotation runs a method once before any tests in the class run.
  2. Step 2: Check method signature requirements

    Methods with @BeforeAll must be static in JUnit 5, so public static void init() is correct.
  3. Final Answer:

    @BeforeAll public static void init() {} -> Option C
  4. Quick Check:

    @BeforeAll + static = run once before all tests [OK]
Hint: @BeforeAll must be static to run once before all tests [OK]
Common Mistakes:
  • Using @BeforeEach instead of @BeforeAll for once-only setup
  • Not making @BeforeAll method static
  • Confusing @AfterEach with setup annotations
3. Consider this JUnit 5 test class snippet:
class SampleTest {
  static int counter = 0;

  @BeforeEach
  void beforeEach() {
    counter++;
  }

  @Test
  void testOne() {}

  @Test
  void testTwo() {}

  @AfterAll
  static void afterAll() {
    System.out.println(counter);
  }
}

What will be printed when the tests run?
medium
A. 2
B. 1
C. 0
D. Compilation error

Solution

  1. Step 1: Analyze the lifecycle annotations and method signatures

    The @AfterAll method must be static, which it is. However, counter is static and incremented in @BeforeEach which is non-static, so no issue there.
  2. Step 2: Check for JUnit 5 rules on lifecycle methods

    JUnit 5 requires @BeforeEach and @AfterEach methods to be non-static, which is correct here. But @AfterAll is static, so no problem.
  3. Step 3: Identify the problem

    However, the class is missing the @TestInstance(Lifecycle.PER_CLASS) annotation if we want to use static fields properly with lifecycle hooks. Without it, static fields are fine but the test runner may not allow static @AfterAll without this annotation in some setups.
  4. Step 4: Confirm if code compiles

    Actually, this code compiles and runs fine. The counter increments twice (once per test), so 2 is printed.
  5. Final Answer:

    2 -> Option A
  6. Quick Check:

    Counter increments twice = 2 printed [OK]
Hint: Each @BeforeEach runs before every test, incrementing counter [OK]
Common Mistakes:
  • Assuming @AfterAll cannot access static fields
  • Thinking counter resets between tests
  • Confusing static and instance method requirements
4. Identify the error in this JUnit 5 test class:
class TestExample {
  @BeforeAll
  void setup() {
    System.out.println("Setup");
  }

  @Test
  void test() {
    System.out.println("Test running");
  }
}
medium
A. Method annotated with @BeforeAll must be static
B. Method annotated with @Test must be static
C. Missing @AfterEach method
D. No error, code is correct

Solution

  1. Step 1: Check @BeforeAll method requirements

    In JUnit 5, methods annotated with @BeforeAll must be static unless the test class is annotated with @TestInstance(Lifecycle.PER_CLASS).
  2. Step 2: Verify method signature

    The setup() method is not static, and the class lacks @TestInstance, so this causes a runtime error.
  3. Final Answer:

    Method annotated with @BeforeAll must be static -> Option A
  4. Quick Check:

    @BeforeAll requires static method without @TestInstance [OK]
Hint: @BeforeAll methods must be static unless @TestInstance used [OK]
Common Mistakes:
  • Thinking @Test methods must be static
  • Believing missing @AfterEach is an error
  • Ignoring static requirement for @BeforeAll
5. You want to open a database connection once before all tests and close it once after all tests in a JUnit 5 class. Which setup is best practice?
hard
A. Use @BeforeEach to open and @AfterEach to close the connection
B. Open and close connection inside each test method manually
C. Use @BeforeAll non-static method to open and @AfterAll non-static method to close
D. Use @BeforeAll static method to open and @AfterAll static method to close the connection

Solution

  1. Step 1: Understand resource management scope

    Opening a database connection once before all tests and closing it once after all tests saves time and resources.
  2. Step 2: Choose correct lifecycle hooks

    @BeforeAll and @AfterAll run once per test class, ideal for this purpose. They must be static methods unless using @TestInstance(Lifecycle.PER_CLASS).
  3. Final Answer:

    Use @BeforeAll static method to open and @AfterAll static method to close the connection -> Option D
  4. Quick Check:

    Open/close once with @BeforeAll/@AfterAll static methods [OK]
Hint: Use @BeforeAll/@AfterAll static for one-time setup/teardown [OK]
Common Mistakes:
  • Using @BeforeEach/@AfterEach causing repeated open/close
  • Opening/closing inside each test wastes resources
  • Using non-static @BeforeAll/@AfterAll without @TestInstance
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard