Unit testing in Java means testing small pieces of code — usually one method or one class — in isolation. The most common testing framework for modern Java projects is JUnit 5, also known as JUnit Jupiter.
This guide shows the basic steps to start writing unit tests with JUnit.
1. Add JUnit to Your Project
If you use Maven, add JUnit 5 to your pom.xml:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.11.4</version>
<scope>test</scope>
</dependency>
You should also make sure Maven Surefire can run JUnit 5 tests:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.2</version>
</plugin>
</plugins>
</build>
If you use Gradle, add:
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.11.4'
}
test {
useJUnitPlatform()
}
2. Create a Class to Test
Suppose you have a simple calculator class:
package org.kodejava;
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int divide(int a, int b) {
if (b == 0) {
throw new IllegalArgumentException("Divider cannot be zero");
}
return a / b;
}
}
This class has two methods:
add()returns the sum of two numbers.divide()divides two numbers and rejects division by zero.
3. Create a Test Class
JUnit test classes are usually placed under:
src/test/java
For the Calculator class, create:
src/test/java/org/kodejava/CalculatorTest.java
Example test class:
package org.kodejava;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class CalculatorTest {
private final Calculator calculator = new Calculator();
@Test
void addReturnsSumOfTwoNumbers() {
int result = calculator.add(2, 3);
assertEquals(5, result);
}
@Test
void divideReturnsQuotient() {
int result = calculator.divide(10, 2);
assertEquals(5, result);
}
@Test
void divideThrowsExceptionWhenDividerIsZero() {
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> calculator.divide(10, 0)
);
assertEquals("Divider cannot be zero", exception.getMessage());
}
}
4. Understand the Basic JUnit Annotations
The most important annotation is:
@Test
It marks a method as a test method.
Example:
@Test
void addReturnsCorrectResult() {
assertEquals(4, 2 + 2);
}
Common JUnit 5 annotations include:
| Annotation | Purpose |
|---|---|
@Test |
Marks a method as a test |
@BeforeEach |
Runs before each test method |
@AfterEach |
Runs after each test method |
@BeforeAll |
Runs once before all tests |
@AfterAll |
Runs once after all tests |
@Disabled |
Temporarily disables a test |
Example using @BeforeEach:
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class CalculatorTest {
private Calculator calculator;
@BeforeEach
void setUp() {
calculator = new Calculator();
}
@Test
void addReturnsSumOfTwoNumbers() {
assertEquals(5, calculator.add(2, 3));
}
}
5. Use Assertions
Assertions check whether the result is what you expect.
Common assertions:
assertEquals(expected, actual);
assertTrue(condition);
assertFalse(condition);
assertNull(value);
assertNotNull(value);
assertThrows(ExceptionType.class, executable);
Example:
package org.kodejava;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class StringTest {
@Test
void stringShouldContainText() {
String message = "Hello JUnit";
assertNotNull(message);
assertTrue(message.contains("JUnit"));
assertEquals(11, message.length());
}
}
6. Follow the Arrange, Act, Assert Pattern
A common structure for unit tests is:
- Arrange — prepare input data and objects.
- Act — call the method being tested.
- Assert — verify the result.
Example:
@Test
void addReturnsSumOfTwoNumbers() {
// Arrange
Calculator calculator = new Calculator();
// Act
int result = calculator.add(2, 3);
// Assert
assertEquals(5, result);
}
This makes tests easier to read and maintain.
7. Run the Tests
With Maven:
mvn test
With Gradle:
./gradlew test
Most IDEs also let you right-click the test class or test method and choose Run Test.
8. Naming Test Methods
Use descriptive names, so it is clear what behavior is being tested.
Good examples:
void addReturnsSumOfTwoNumbers()
void divideThrowsExceptionWhenDividerIsZero()
void loginFailsWhenPasswordIsInvalid()
Avoid vague names like:
void test1()
void testAdd()
void shouldWork()
9. What Should You Test?
Good candidates for unit tests include:
- Business rules
- Calculations
- Validation logic
- Conditional logic
- Exception handling
- Data transformation methods
For example, test things like:
discount is applied correctly
invalid email is rejected
zero quantity throws an exception
user cannot withdraw more than their balance
You usually do not need to unit test:
- Simple getters and setters
- Framework-generated behavior
- Code with no meaningful logic
- External services directly
10. Example: Testing a Realistic Service Class
Class to test:
package org.kodejava.order;
public class DiscountService {
public double applyDiscount(double price, double discountPercent) {
if (price < 0) {
throw new IllegalArgumentException("Price cannot be negative");
}
if (discountPercent < 0 || discountPercent > 100) {
throw new IllegalArgumentException("Discount must be between 0 and 100");
}
return price - (price * discountPercent / 100);
}
}
Test class:
package org.kodejava.order;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class DiscountServiceTest {
private final DiscountService discountService = new DiscountService();
@Test
void applyDiscountReturnsDiscountedPrice() {
double result = discountService.applyDiscount(100.0, 10.0);
assertEquals(90.0, result);
}
@Test
void applyDiscountRejectsNegativePrice() {
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> discountService.applyDiscount(-100.0, 10.0)
);
assertEquals("Price cannot be negative", exception.getMessage());
}
@Test
void applyDiscountRejectsInvalidDiscountPercent() {
assertThrows(
IllegalArgumentException.class,
() -> discountService.applyDiscount(100.0, 120.0)
);
}
}
For floating-point values, you can also provide a delta:
assertEquals(90.0, result, 0.001);
Summary
To start unit testing in Java with JUnit:
- Add JUnit 5 to your project.
- Put test classes under
src/test/java. - Mark test methods with
@Test. - Use assertions such as
assertEquals()andassertThrows(). - Follow the Arrange, Act, Assert pattern.
- Run tests with Maven, Gradle, or your IDE.
A simple JUnit test looks like this:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class CalculatorTest {
@Test
void addReturnsSum() {
Calculator calculator = new Calculator();
assertEquals(5, calculator.add(2, 3));
}
}
