How to test void methods
Testing void
methods in JUnit is a common task—especially when you're testing side effects, like updating state, writing to logs, saving to a database, etc.
Here’s a comprehensive guide on how to test void
methods using JUnit 5, with or without Mockito.
✅ 1. Test Side Effects Directly (No Mockito)
If the void
method changes state or causes observable behavior, assert those outcomes.
🔹 Example: Testing a void
method that changes internal state
public class Counter {
private int count = 0;
public void increment() {
count++;
}
public int getCount() {
return count;
}
}
🧪 JUnit Test
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CounterTest {
@Test
void testIncrement() {
Counter counter = new Counter();
counter.increment();
assertEquals(1, counter.getCount());
}
}
✅ 2. Use Mockito to Verify Method Calls (void method interactions)
🔹 Example: You want to ensure a void
method was called (e.g., logger.log()
)
public class UserService {
private Logger logger;
public UserService(Logger logger) {
this.logger = logger;
}
public void createUser(String name) {
// Do some user creation logic
logger.log("User created: " + name); // void method
}
}
🧪 JUnit + Mockito Test
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;
class UserServiceTest {
@Test
void testCreateUserLogsMessage() {
Logger mockLogger = mock(Logger.class);
UserService service = new UserService(mockLogger);
service.createUser("Alice");
verify(mockLogger).log("User created: Alice");
}
}
✅ 3. Use doNothing()
/ doThrow()
for void methods with side effects
This is useful when mocking void
methods that might throw exceptions (e.g., emailService.send()
).
doNothing().when(mockEmailService).sendEmail(anyString());
Or:
doThrow(new RuntimeException("SMTP down")).when(mockEmailService).sendEmail("[email protected]");
✅ 4. Capture Arguments Passed to void
Methods
Use ArgumentCaptor
to check what was passed to a void
method.
import org.mockito.ArgumentCaptor;
@Test
void testLogContent() {
Logger mockLogger = mock(Logger.class);
UserService service = new UserService(mockLogger);
service.createUser("Bob");
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(mockLogger).log(captor.capture());
assertTrue(captor.getValue().contains("Bob"));
}
📌 Summary
Goal | Approach |
---|---|
Assert state change | Check state before & after |
Check interaction (mocked) | Use Mockito.verify() |
Simulate exception | Use doThrow() with mocked method |
Check argument values | Use ArgumentCaptor |