Spring Boot: From Basics to Production · Testing Spring Boot Applications
Unit Tests with JUnit 5 and Mockito
Test services fast, without starting Spring.
Most tests should be plain JUnit 5 unit tests with no Spring context: construct the class with its dependencies (thanks to constructor injection), using Mockito mocks or simple fakes for collaborators. Use AssertJ for fluent assertions and @ParameterizedTest for case tables. These run in milliseconds.
@ExtendWith(MockitoExtension.class)
class CheckoutServiceTest {
@Mock OrderRepository orders;
@Mock PaymentGateway payments;
@InjectMocks CheckoutService service;
@Test
void savesPaidOrderAfterSuccessfulCharge() {
var cart = Cart.of(new Line("SKU-1", 2, 1_000));
when(payments.charge(any(), eq("tok_123"))).thenReturn(new PaymentResult("pay_1"));
when(orders.save(any())).thenAnswer(inv -> inv.getArgument(0));
Order order = service.checkout(cart, "tok_123");
assertThat(order.status()).isEqualTo(OrderStatus.PAID);
assertThat(order.paymentReference()).isEqualTo("pay_1");
}
@ParameterizedTest
@CsvSource({"0, false", "1, true", "99, true"})
void validatesQuantity(int qty, boolean valid) {
assertThat(Line.isValidQuantity(qty)).isEqualTo(valid);
}
}
Common pitfalls
- Using @SpringBootTest for every test (slow suites).
- Mocking value objects or the class under test.
- Verifying every interaction instead of outcomes.
Key points
- Plain unit tests by default
- Mockito for collaborators
- AssertJ + parameterized tests
Further reading: JUnit 5 User Guide
Practice questions
Why does constructor injection make unit testing easier?
Answer
You can create the class with new and pass mocks or fakes directly, without starting a Spring context.
When should a test verify interactions with a mock?
Answer
When the interaction is the observable outcome (e.g., an email was sent or a payment charged); otherwise assert on returned values or state.
Open in the app to mark lessons complete, take notes and track your progress.