How to test microservices
Structured Java interview answer with junior, middle, and senior-level explanation.
🟢 Junior Level
Three levels of testing:
- Unit tests — testing a single class/method
- Integration tests — testing interaction with DB, external services
- Contract tests — verifying API compatibility between services
// Unit test
@Test
void testOrderCalculation() {
OrderService service = new OrderService();
Order order = service.createOrder(List.of(item1, item2));
assertEquals(100, order.total());
}
🟡 Middle Level
Integration tests
@SpringBootTest
@Testcontainers
class OrderServiceIntegrationTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15");
@Test
void testCreateOrder() {
Order order = orderService.createOrder(request);
assertNotNull(order.getId());
}
}
Contract tests (Pact)
@Provider("Order Service")
@Consumer("User Service")
public class OrderServiceContractTest {
@TestTemplate
void testGetUserOrders(PactVerificationContext context) {
// Interaction = a single request-response between consumer and provider.
// Pact verifies that the provider can handle the request the consumer expects.
// Contract tests catch breaking changes in API before they reach production.
context.verifyInteraction();
}
}
Common mistakes
- Tests with real services:
Network call → real Payment Service → slow (100-500ms per request) and unstable (network can fail, service can be unavailable). Solution: mock or testcontainers
🔴 Senior Level
Test pyramid
/ E2E \ — few (10%)
/ Integration \ — medium (20%)
/ Unit \ — many (70%)
Consumer-driven contracts
User Service (consumer) defines contract → Order Service (provider) verifies
Production Experience
Testcontainers:
@Testcontainers
class UserRepositoryTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15");
// @DynamicPropertySource (Spring Boot 2.2.6+) — dynamically passes container
// ports to Spring Environment before context initialization.
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
}
}
Best Practices
✅ Test pyramid
✅ Testcontainers for integration
✅ Contract tests for API
✅ Mock external services
✅ CI/CD pipeline with tests
❌ Only E2E tests
❌ Tests with real services
❌ Without contract tests
🎯 Interview Cheat Sheet
Must know:
- Test pyramid: Unit (70%) → Integration (20%) → E2E (10%)
- Unit tests — single class/method, fast, isolated
- Integration tests — interaction with DB, external services (Testcontainers)
- Contract tests (Pact) — verify API compatibility between services, catch breaking changes
- Testcontainers — Docker containers for integration tests (PostgreSQL, Kafka)
- Consumer-driven contracts: consumer defines contract, provider verifies
- Mock external services — do not test with real ones (slow, unstable)
Frequent follow-up questions:
- Why contract tests? Catch breaking changes in API before production — consumer expects X, provider must deliver X.
- Testcontainers vs mock? Testcontainers = real service in Docker (more reliable), mock = stub (faster).
- Why not only E2E? E2E is slow, fragile, hard to debug. Unit tests are faster, more stable.
- What does @DynamicPropertySource do? Dynamically passes container ports to Spring Environment before context initialization.
Red flags (NOT to say):
- “Only E2E tests are enough” — no, slow, fragile, hard to debug
- “Tests with real Payment Service” — no, slow (100-500ms) and unstable
- “Contract tests are not needed, we have Swagger” — Swagger describes API, contract tests verify compatibility
- “Unit tests = integration tests” — no, unit = single class, integration = interaction
Related topics:
- [[26. What tools are used for microservices orchestration]]
- [[15. How to organize communication between microservices]]
- [[22. What is distributed tracing]]
- [[9. What is API Gateway and what problems does it solve]]
- [[17. How to ensure fault tolerance of microservices]]