JUnit
TL;DR
- JUnit is the industry-standard testing framework for Java.
- JUnit 5 (Jupiter) is the current modern version, consisting of the Platform (runner), Jupiter (API), and Vintage (JUnit 4 backwards compatibility).
- Tests are identified using the
@Testannotation, and lifecycle is managed via@BeforeEach,@AfterEach,@BeforeAll, and@AfterAll.
Concept
To verify that your code works, you could just write a public static void main method, pass in some inputs, and print the outputs. However, this doesn’t scale. You need an automated way to run hundreds of tests instantly and get a clear pass/fail report.
JUnit provides the framework to do this. You write standard Java methods, annotate them with @Test, and use Assertions to verify that the output of your code matches the expected output. Build tools like Maven/Gradle automatically find these @Test methods, run them in isolation, and generate reports.
Examples
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
class CalculatorTest {
private Calculator calc;
// Runs ONCE before all tests (must be static)
@BeforeAll
static void initAll() {
System.out.println("Starting test suite...");
}
// Runs before EVERY individual test
@BeforeEach
void setUp() {
calc = new Calculator();
}
// The actual test method
@Test
@DisplayName("1 + 1 should equal 2")
void testAddition() {
int result = calc.add(1, 1);
assertEquals(2, result, "Addition logic failed");
}
// Testing Exceptions
@Test
void testDivisionByZero() {
Exception exception = assertThrows(ArithmeticException.class, () -> {
calc.divide(10, 0);
});
assertEquals("/ by zero", exception.getMessage());
}
// Runs after EVERY individual test
@AfterEach
void tearDown() {
calc = null; // Cleanup
}
}
Interview Questions
Q: What is the difference between @BeforeEach and @BeforeAll?
A: - @BeforeEach (JUnit 5) or @Before (JUnit 4) runs before every single @Test method. It is used to set up a fresh environment or instantiate fresh objects for each test to ensure tests do not bleed state into each other.
@BeforeAll(JUnit 5) or@BeforeClass(JUnit 4) runs exactly once before any tests in the class run. It must be astaticmethod. It is used for expensive setups, like opening a database connection or spinning up a test container, which all tests will share.
Q: Why does JUnit create a new instance of the Test Class for every test method?
A: By default, if you have 5 @Test methods in CalculatorTest, JUnit actually creates 5 separate instances of the CalculatorTest class. It does this to guarantee Test Isolation. If one test accidentally mutates a class-level variable, it won’t affect the next test, preventing flaky tests that randomly pass or fail depending on execution order. (You can change this behavior in JUnit 5 using @TestInstance(Lifecycle.PER_CLASS)).