What is the difference between @SpringBootTest, @WebMvcTest, and @DataJpaTest?
Must Know🌱 Fresher
Annotation
Loads
Use for
@SpringBootTest
The full application context (every bean)
End-to-end / integration tests exercising real wiring
@WebMvcTest
Only the web layer (controllers, filters, MVC config) — services/repositories are mocked
Fast, isolated controller tests via MockMvc
@DataJpaTest
Only JPA-related beans (repositories, entity manager), with an in-memory DB by default
Testing repository queries in isolation
Spring Testing
2
What is MockMvc, and how do you use it to test a controller?
Must Know🌱 Fresher
MockMvc simulates HTTP requests against your controllers without starting a real embedded server — it dispatches directly into the Spring MVC infrastructure, making controller tests fast and able to run without opening any network port.
What is the difference between @Mock, @Spy, and @MockBean?
Important📊 Mid
@Mock (plain Mockito) — a fully fake object; every method returns a default/stubbed value unless you explicitly configure it with when(...).
@Spy — wraps a real object; calls go to the real implementation unless you explicitly stub a specific method, useful when you want most behavior real but need to override or verify just one method.
@MockBean — a Spring Boot Test annotation, not plain Mockito: it creates a Mockito mock and replaces the matching bean in the Spring ApplicationContext with it, so any other bean that gets it autowired (e.g. a controller under test) receives the mock instead of the real bean.
Spring TestingMockito
4
What are Testcontainers, and why use them instead of an in-memory database like H2?
Important📊 Mid
Testcontainers spins up real Docker containers (Postgres, Kafka, Redis...) for integration tests, then tears them down afterward — giving you a test environment that behaves exactly like production, instead of an approximation.
H2 (an in-memory database) is faster to start and needs no Docker, but it's a different database engine than most production stacks (Postgres/MySQL) — SQL dialect differences, constraint behavior, and vendor-specific features (JSON columns, window functions) can all behave subtly differently, letting bugs slip past tests that pass against H2 but fail against the real database. Testcontainers trades a bit of startup speed for tests that accurately reflect production behavior.
What is service discovery, and how does Eureka work?
Important📊 Mid
In a microservices architecture, instances scale up/down and get rescheduled to different hosts/ports constantly — hardcoding "order-service is at 10.0.1.5:8080" breaks the moment it moves. Service discovery solves this: each service instance registers itself with a central registry on startup; any other service asks the registry "where is order-service right now?" instead of using a fixed address.
🧭 Eureka registration & discovery
Order Service instance starts
-> registers itself with Eureka Server: "I'm order-service at 10.0.1.7:8081"
-> sends periodic heartbeats to stay registered
Payment Service needs to call Order Service:
-> asks Eureka: "where are the healthy instances of order-service?"
-> Eureka returns a live list -- Payment Service load-balances across them
-> if an instance stops sending heartbeats, Eureka evicts it from the list
Add spring-cloud-starter-netflix-eureka-client, point it at the Eureka server's URL, and annotate the main class @EnableEurekaClient (or rely on auto-detection in newer Spring Cloud versions) — registration and heartbeats happen automatically after that.
MicroservicesEureka
6
What is a Feign client, and why use it for inter-service calls?
Important📊 Mid
Feign is a declarative HTTP client — instead of manually building requests with RestTemplate or WebClient (URL strings, headers, response parsing), you declare a Java interface describing the remote API, and Feign generates the implementation at runtime.
A Feign clientjava
@FeignClient(name = "order-service") // resolves via service discovery (e.g. Eureka)interfaceOrderClient {
@GetMapping("/orders/{id}")
Order getOrder(@PathVariableLong id);
}
// Usage -- looks like a plain local method call:Order order = orderClient.getOrder(42L);
It integrates natively with service discovery (call by logical service name, not a hardcoded host) and load balancing, and pairs cleanly with resilience libraries (retry, circuit breaker) via simple annotations — which is why it's the conventional default for synchronous inter-service calls in a Spring Cloud microservices stack.
MicroservicesFeign
7
What is a circuit breaker, and why do microservices need one?
Important📊 Mid
A circuit breaker wraps a call to a remote service and tracks its recent failure rate. If failures exceed a threshold, the circuit "opens" — further calls fail immediately (optionally falling back to a default/cached response) without even attempting the network call, for a cooldown period, before "half-opening" to test if the dependency has recovered.
In a microservices architecture, a single slow or failing downstream service can otherwise cause every upstream caller to pile up threads waiting on it, exhausting thread pools and cascading the failure across the whole system. A circuit breaker contains the blast radius: callers fail fast and stay responsive (possibly in a degraded mode) instead of getting dragged down with the failing dependency. See Circuit Breaker / Retry / Bulkhead → for the full pattern (often implemented via Resilience4j in Spring Boot apps).
MicroservicesResilience
8
How do you add a custom health indicator to Spring Boot Actuator?
Optional📊 Mid
Implement HealthIndicator (or extend AbstractHealthIndicator) as a bean — Spring Boot automatically picks it up and folds its result into /actuator/health, alongside built-in checks (disk space, database).
If any indicator reports DOWN, the overall aggregated health status becomes DOWN too — useful for load balancers/orchestrators (Kubernetes readiness probes) deciding whether to route traffic to this instance.