Files
awesome-copilot/skills/spring-boot-testing/references/mockitobean.md
Kartik Dhiman e4fc57f204 feat: add spring-boot-testing skill for Spring Boot 4.0 (#1085)
- Introduced MockMvcTester for AssertJ-style assertions in Spring MVC testing.
- Added @RestClientTest for testing REST clients with MockRestServiceServer.
- Implemented RestTestClient as a modern alternative to TestRestTemplate.
- Documented migration steps from Spring Boot 3.x to 4.0, including dependency and annotation changes.
- Created an overview of test slices to guide testing strategies.
- Included Testcontainers setup for JDBC testing with PostgreSQL and MySQL.
- Enhanced @WebMvcTest documentation with examples for various HTTP methods and validation.
2026-03-20 10:24:37 +11:00

233 lines
4.5 KiB
Markdown

# @MockitoBean
Mocking dependencies in Spring Boot tests (replaces deprecated @MockBean in Spring Boot 4+).
## Overview
`@MockitoBean` replaces the deprecated `@MockBean` annotation in Spring Boot 4.0+. It creates a Mockito mock and registers it in the Spring context, replacing any existing bean of the same type.
## Basic Usage
```java
@WebMvcTest(OrderController.class)
class OrderControllerTest {
@MockitoBean
private OrderService orderService;
@MockitoBean
private UserService userService;
}
```
## Supported Test Slices
- `@WebMvcTest` - Mock service/repository dependencies
- `@WebFluxTest` - Mock reactive service dependencies
- `@SpringBootTest` - Replace real beans with mocks
## Stubbing Methods
### Basic Stub
```java
@Test
void shouldReturnOrder() {
Order order = new Order(1L, "PENDING");
given(orderService.findById(1L)).willReturn(order);
// Test code
}
```
### Multiple Returns
```java
given(orderService.findById(anyLong()))
.willReturn(new Order(1L, "PENDING"))
.willReturn(new Order(2L, "COMPLETED"));
```
### Throwing Exceptions
```java
given(orderService.findById(999L))
.willThrow(new OrderNotFoundException(999L));
```
### Argument Matching
```java
given(orderService.create(argThat(req -> req.getQuantity() > 0)))
.willReturn(1L);
given(orderService.findByStatus(eq("PENDING")))
.willReturn(List.of(new Order()));
```
## Verifying Interactions
### Verify Method Called
```java
verify(orderService).findById(1L);
```
### Verify Never Called
```java
verify(orderService, never()).delete(any());
```
### Verify Count
```java
verify(orderService, times(2)).findById(anyLong());
verify(orderService, atLeastOnce()).findByStatus(anyString());
```
### Verify Order
```java
InOrder inOrder = inOrder(orderService, userService);
inOrder.verify(orderService).findById(1L);
inOrder.verify(userService).getUser(any());
```
## Resetting Mocks
Mocks are reset between tests automatically. To reset mid-test:
```java
Mockito.reset(orderService);
```
## @MockitoSpyBean for Partial Mocking
Use `@MockitoSpyBean` to wrap a real bean with Mockito.
```java
@SpringBootTest
class OrderServiceIntegrationTest {
@MockitoSpyBean
private PaymentGatewayClient paymentClient;
@Test
void shouldProcessOrder() {
doReturn(true).when(paymentClient).processPayment(any());
// Test with real service but mocked payment client
}
}
```
## @TestBean for Custom Test Beans
Register a custom bean instance in the test context:
```java
@SpringBootTest
class OrderServiceTest {
@TestBean
private PaymentGatewayClient paymentClient() {
return new FakePaymentClient();
}
}
```
## Scoping: Singleton vs Prototype
Spring Framework 7+ (Spring Boot 4+) supports mocking non-singleton beans:
```java
@Component
@Scope("prototype")
public class OrderProcessor {
public String process() { return "real"; }
}
@SpringBootTest
class OrderServiceTest {
@MockitoBean
private OrderProcessor orderProcessor;
@Test
void shouldWorkWithPrototype() {
given(orderProcessor.process()).willReturn("mocked");
// Test code
}
}
```
## Common Patterns
### Mocking Repository in Service Test
```java
@SpringBootTest
class OrderServiceTest {
@MockitoBean
private OrderRepository orderRepository;
@Autowired
private OrderService orderService;
@Test
void shouldCreateOrder() {
given(orderRepository.save(any())).willReturn(new Order(1L));
Long id = orderService.createOrder(new OrderRequest());
assertThat(id).isEqualTo(1L);
verify(orderRepository).save(any(Order.class));
}
}
```
### Multiple Mocks of Same Type
Use bean names:
```java
@MockitoBean(name = "primaryDataSource")
private DataSource primaryDataSource;
@MockitoBean(name = "secondaryDataSource")
private DataSource secondaryDataSource;
```
## Migration from @MockBean
### Before (Deprecated)
```java
@MockBean
private OrderService orderService;
```
### After (Spring Boot 4+)
```java
@MockitoBean
private OrderService orderService;
```
## Key Differences from Mockito @Mock
| Feature | @MockitoBean | @Mock |
| ------- | ------------ | ----- |
| Context integration | Yes | No |
| Spring lifecycle | Participates | None |
| Works with @Autowired | Yes | No |
| Test slice support | Yes | Limited |
## Best Practices
1. Use `@MockitoBean` only when Spring context is involved
2. For pure unit tests, use Mockito's `@Mock` or `Mockito.mock()`
3. Always verify interactions that have side effects
4. Don't verify simple queries (stubbing is enough)
5. Reset mocks if test modifies shared mock state