Before Annotation

T 
/** 
 * JUNIT LIFECYCLE ANNOTATIONS
 * ---------------------------
 * JUnit provides several annotations to control test initialization
 * and cleanup. Understanding these is essential for writting clean and
 * independent test cases.
 * 
 * @Before
 *  - Runs BEFORE EACH test method.
 *  - JUnit creates a NEW instance of the test class for every test.
 *  - Use it to set up fresh objects so tests do not affect one another.
 * 
 * @After
 *  - Runs AFTER EACH test method.
 *  - Use it to clean up resources (files, connections, locks).
 * 
 * @BeforeClass
 *  - Runs ONCE before all tests in the class.
 *  - Method MUST be static.
 *  - Use for expensive setup (database, cache, servers).
 * 
 * @AfterClass
 *  - Runs ONCE after all tests in the class.
 *  - Method MUST be static.
 *  - Use for releasing shared resources.
 * 
 * In this example:
 *  - The @Before method initializes the Squares object before EACH test.
 *  - Both test gets their own fresh, independent instance.
 */

package com.minte9.junit.annotations;

import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;

public class BeforeAnnotationTest {

    private Squares squares;

    @Before 
    public void executedBeforeEach() {

        squares = new Squares();
        squares.add(3);  // 9
        squares.add(5);  // 25

        System.out.println("Squares initialized!");  
        // Prints twice (once per each test)
    }
    
    @Test 
    public void average() {
        assertEquals(squares.average(), 17);
    }

    @Test 
    public void sum() {
        assertEquals(squares.sum(), 34);
    }
}

class Squares {

    private final List<Integer> squares = new ArrayList<>();

    public void add(int x) {
        squares.add(x * x); 
    }

    public int average() { 
        return sum() / squares.size(); 
    }

    public int sum() { 
        return squares.stream().mapToInt(Integer::intValue).sum();
    }
}

BeforeClass Annotation

T 
/**
 * @BeforeClass - RUNCE ONCE BEFORE ALL TEST
 * -----------------------------------------
 * JUnit provides @BeforeClass for expensive setup operations that should
 * run only a single time before any test methods are executed.
 * 
 * In this example:
 *  - Square collection is created ONLY ONCE.
 *  - Both tests use the same initialized data.
 */

package com.minte9.junit.annotations;

import static org.junit.Assert.assertEquals;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;

public class BeforeClassAnnotationTest {

    private static SQ squares;

    @BeforeClass 
    static public void executedBeforeOnce() {
        
        squares = new SQ();
        squares.add(3);  // 9
        squares.add(5);  // 25

        System.out.println("Squares initialized!");
        // Exectuted once for the entire class
    }
    
    @Test 
    public void average() {
        assertEquals(squares.average(), 17);
    }

    @Test 
    public void sum() {
        assertEquals(squares.sum(), 34);
    }
}

class SQ {

    private List<Integer> squares = new ArrayList<>();

    public void add(int x) {
        squares.add(x * x); 
    }

    public int average() { 
        return sum() / squares.size(); 
    }

    public int sum() { 
        return squares.stream().mapToInt(Integer::intValue).sum();
    }
}

After Annotation

T 
/** 
 * @After - EXECUTED AFTER EACH TEST
 * ---------------------------------
 * The @After annotation marks a method that JUnit runs "after each" 
 * individual test method completes.
 * 
 * LIFECYCLE (JUnit 4 creates a new instance per test):
 * 
 *      @Before
 *      @Test
 *      @After
 * 
 *      @Before
 *      @Test
 *      @After
 * 
 * WHY USE @After?
 * ---------------
 * It is ideal for cleanup operations such as:
 *  - closing database connections
 *  - delete temporary files
 *  - resetting shared state
 *  - releasing external resources
 */

package com.minte9.junit.annotations;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class AfterAnnotationTest {
    
    @Before 
    public void start() {
        System.out.println("Db connection start");
    }

    @Test 
    public void run() {
        System.out.println("App run test");
    }

    @After 
    public void end() {
        System.out.println("Db connection close");
    }

    /*
        Db connection start
        App run test
        Db connection close
    */
}






Questions and answers:
Clink on Option to Answer




1. When does a method annotated with @Before run?

  • a) Before each individual test method
  • b) Only once before the entire test class

2. How many times does JUnit create an instance of the test class in JUnit

  • a) Once for the whole class
  • b) Once per test method

3. What must be true about a method annotated with @BeforeClass?

  • a) It must be static
  • b) It must return a value

4. When does @BeforeClass execute?

  • a) One time before all tests run
  • b) Before every test

5. What is the purpose of @After?

  • a) To clean up after each test
  • b) To clean up once after the entire suite

6. Which lifecycle order is correct for each test method?

  • a) @Test → @Before → @After
  • b) @Before → @Test → @After

7. Why is @Before useful in the Squares example?

  • a) It gives each test a fresh, isolated instance
  • b) It prevents the test from running more than once

8. Why is @BeforeClass useful?

  • a) It performs expensive setup only once (database, cache, etc.)
  • b) It resets state before every test


References: