In this post under JUnit, I will explain with example the purpose of “TestInstance” annotation.
By default when we execute a test class, for each test method, a separate instance of test class is created.
Lets see an example. For our example I will create the below “Calculator” class that has to be tested.
Calculator
package package13;
public class Calculator {
private int x;
private int y;
public Calculator(int x, int y) {
this.x = x;
this.y = y;
}
public int add() {
return this.x + this.y;
}
public int substract() {
return this.x - this.y;
}
public int multipy() {
return this.x * this.y;
}
public int divide() {
return this.x/this.y;
}
}
The above class has to tested. In the class, we have two variables “x” and “y” and then “add”, “substract”, “multiply”, and “divide” methods which perform corresponding actions on both the variables.
Below is the test class that we will write
CalculatorTestInstancePerMethod
package package13;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
public class CalculatorTestInstancePerMethod {
private static int count = 0;
public CalculatorTestInstancePerMethod() {
System.out.println("Test instance count: " + count);
count = count + 1;
}
@Test
public void testAdd() {
Calculator calculator = new Calculator(10, 5);
assertEquals(15, calculator.add());
}
@Test
public void testSubtract() {
Calculator calculator = new Calculator(6, 5);
assertEquals(1, calculator.substract());
}
@Test
public void testMultiply() {
Calculator calculator = new Calculator(7, 5);
assertEquals(35, calculator.multipy());
}
@Test
public void testDivide() {
Calculator calculator = new Calculator(15, 5);
assertEquals(3, calculator.divide());
}
}
In the above class, I have added test methods to test all the “Calculator” class methods.
In the constructor, I have written the code, which will keep track of how many instances of test class “CalculatorTestInstancePerMethod” is created.
Below is the output when we execute the test class
Output 1
Test instance count: 0
Test instance count: 1
Test instance count: 2
Test instance count: 3
As you can see from the above output, for 4 test methods the JUnit framework is creating 4 instances of “CalculatorTestInstancePerMethod” class.
We can change that default behavior by using “@TestInstance” annotation as shown below
CalculatorTestInstancePerClass
1 package package13;
2
3 import static org.junit.jupiter.api.Assertions.assertEquals;
4
5 import org.junit.jupiter.api.Test;
6 import org.junit.jupiter.api.TestInstance;
7 import org.junit.jupiter.api.TestInstance.Lifecycle;
8
9 @TestInstance(Lifecycle.PER_CLASS)
10 public class CalculatorTestInstancePerClass {
11 private static int count = 0;
12
13 public CalculatorTestInstancePerClass() {
14 System.out.println("Test instance count: " + count);
15 count = count + 1;
16 }
17
18 @Test
19 public void testAdd() {
20 Calculator calculator = new Calculator(10, 5);
21 assertEquals(15, calculator.add());
22 }
23
24 @Test
25 public void testSubtract() {
26 Calculator calculator = new Calculator(6, 5);
27 assertEquals(1, calculator.substract());
28 }
29
30 @Test
31 public void testMultiply() {
32 Calculator calculator = new Calculator(7, 5);
33 assertEquals(35, calculator.multipy());
34 }
35
36 @Test
37 public void testDivide() {
38 Calculator calculator = new Calculator(15, 5);
39 assertEquals(3, calculator.divide());
40 }
41 }
In the above code, at line 9 I have applied the “@TestInstance” annotation at class level and passed “Lifecycle.PER_CLASS” as a argument to the annotation.
This will make sure that JUnit framework creates only one instance of test class regardless of how many test methods are there in the class.
Below is the output
Output 2
Test instance count: 0
From the output you can see only one instance of “CalculatorTestInstancePerClass” is created.
In this way we can use “@TestInstance” annotation.