Integration Testing with Spring Boot
TL;DR
- Spring Boot makes integration testing effortless via the
@SpringBootTestannotation. - It loads the entire Spring Application Context, connecting to databases and wiring all Beans.
- You can use
@MockBeanto selectively mock specific dependencies (like 3rd-party APIs) while keeping the rest of the application real.
Concept
When you annotate a test class with @SpringBootTest, Spring Boot effectively starts up your entire application just as if you had run the main method. It auto-configures the database, sets up Hibernate, and creates the REST controllers.
Because starting the entire app is slow, you can use “Sliced” testing. Annotations like @DataJpaTest or @WebMvcTest tell Spring: “Only load the Database beans” or “Only load the HTTP Controller beans.” This provides a fast, focused integration test.
If your app charges a credit card via Stripe, you absolutely do not want your automated tests hitting the real Stripe API. You use @MockBean on the StripeService. Spring loads the real app, but secretly swaps the StripeService bean with a Mockito mock.
Examples
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class OrderFlowIntegrationTest {
// REAL Beans, wired up to an In-Memory H2 Database automatically
@Autowired
private OrderService orderService;
@Autowired
private OrderRepository orderRepository;
// FAKE Bean. Spring will replace the real PaymentClient with this Mock
// and inject it into the OrderService!
@MockBean
private StripePaymentClient paymentClient;
@Test
void testSuccessfulOrderFlow() {
// 1. Program the mock to simulate a successful API call to Stripe
when(paymentClient.chargeCard(anyDouble())).thenReturn("TXN_12345");
// 2. Trigger the real application logic
orderService.checkout(100.00);
// 3. Verify the real database actually saved the order
assertEquals(1, orderRepository.count());
// 4. Verify the system actually tried to call Stripe
verify(paymentClient, times(1)).chargeCard(100.00);
}
}
Interview Questions
Q: What is the difference between @Mock and @MockBean?
A: - @Mock is a standard Mockito annotation used in pure Unit Tests. Spring knows nothing about it.
@MockBeanis a Spring Boot annotation. It creates a Mockito mock AND actively registers it inside the Spring Application Context. If Spring was preparing to inject a realPaymentClientinto a service, it intercepts it and injects the@MockBeaninstead.
Q: Does @SpringBootTest start a real HTTP server (Tomcat)?
A: By default, no. @SpringBootTest loads the web components, but mocks the web environment (HTTP requests are simulated entirely in-memory using MockMvc), making it very fast.
If you want to test actual HTTP networking (like a real client calling localhost:8080), you must configure it using @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT). Spring will spin up an actual Tomcat server on a random port. You can then use TestRestTemplate to send real HTTP requests to it.