Junit 5 Test Instance Per Class Lifecycle

When Lifecycle.PER_CLASS is used then it will create a new test instance once per class only, so all the instance variables of that test class will retain their values from the last iteration.

if we are using Lifecycle.PER_CLASS but still needs to reinitialize all the instance variables of the test class. we can take advantage of @BeforeEach or @AfterEach methods. methods annotated with these annotations will run every time before and after the test case.

package org.wesome.junit5;

public class AppleCalculator {
    public int addApple(int apple1, int apple2) {
        return apple1 + apple2;
    }
}
package org.wesome.junit5;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;

import static org.junit.jupiter.api.Assertions.assertEquals;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class AppleCalculatorTest {
    public AppleCalculatorTest() {
        System.out.println("AppleCalculatorTest instantiated");
    }

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

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

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

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

    private int instanceVar = 0;

    @Test
    void addAppleTest1() {
        instanceVar += 1;
        System.out.println("AppleCalculatorTest.addAppleTest1#instanceVar = " + instanceVar);
        AppleCalculator appleCalculator = new AppleCalculator();
        assertEquals(2, appleCalculator.addApple(1, 1), "1 apple + 1 apple is 2 apple");
    }

    @Test
    void addAppleTest2() {
        instanceVar += 1;
        System.out.println("AppleCalculatorTest.addAppleTest2#instanceVar = " + instanceVar);
        AppleCalculator appleCalculator = new AppleCalculator();
        assertEquals(2, appleCalculator.addApple(1, 1), "1 apple + 1 apple is 2 apple");
    }
}
plugins {
    id 'java'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
}
AppleCalculatorTest instantiated
AppleCalculatorTest BeforeAll
AppleCalculatorTest BeforeEach
AppleCalculatorTest.addAppleTest1#instanceVar = 1
AppleCalculatorTest AfterEach
AppleCalculatorTest BeforeEach
AppleCalculatorTest.addAppleTest2#instanceVar = 2
AppleCalculatorTest AfterEach
AppleCalculatorTest AfterAll

If more than 1 test class needs to have Lifecycle.PER_CLASS behavior, then annotating all test classes with the same annotation is not a good idea. to avoid redundancy, we can set this property in the JUnit Platform configuration file.

create a file name junit-platform.properties in src/test/resources.

junit.jupiter.testinstance.lifecycle.default = per_class
package org.wesome.junit5;

public class AppleCalculator {
    public int addApple(int apple1, int apple2) {
        return apple1 + apple2;
    }
}
package org.wesome.junit5;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AppleCalculatorTest {
    public AppleCalculatorTest() {
        System.out.println("AppleCalculatorTest instantiated");
    }

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

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

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

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

    private int instanceVar = 0;

    @Test
    void addAppleTest1() {
        instanceVar += 1;
        System.out.println("AppleCalculatorTest.addAppleTest1#instanceVar = " + instanceVar);
        AppleCalculator appleCalculator = new AppleCalculator();
        assertEquals(2, appleCalculator.addApple(1, 1), "1 apple + 1 apple is 2 apple");
    }

    @Test
    void addAppleTest2() {
        instanceVar += 1;
        System.out.println("AppleCalculatorTest.addAppleTest2#instanceVar = " + instanceVar);
        AppleCalculator appleCalculator = new AppleCalculator();
        assertEquals(2, appleCalculator.addApple(1, 1), "1 apple + 1 apple is 2 apple");
    }
}
plugins {
    id 'java'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
}
Using test instance lifecycle mode 'PER_CLASS' set via the 'junit.jupiter.testinstance.lifecycle.default' configuration parameter.
AppleCalculatorTest instantiated
AppleCalculatorTest BeforeAll
AppleCalculatorTest BeforeEach
AppleCalculatorTest.addAppleTest1#instanceVar = 1
AppleCalculatorTest AfterEach
AppleCalculatorTest BeforeEach
AppleCalculatorTest.addAppleTest2#instanceVar = 2
AppleCalculatorTest AfterEach
AppleCalculatorTest AfterAll

follow us on