Skip to main content
Advertisement

16.3 Service-Layer Slice Testing with Mockito

Mockito lets you cut dependencies between layers in unit tests — no real DB or external API connections required.

1. @Mock and @InjectMocks

@ExtendWith(MockitoExtension.class)
class ProductServiceTest {

@Mock
private ProductRepository productRepository;

@Mock
private CacheManager cacheManager;

@InjectMocks
private ProductService productService;

@Test
@DisplayName("When no cache hit, product is fetched from DB.")
void fetch_product_from_db() {
// Given
Long productId = 1L;
Product mockProduct = new Product(productId, "Spring Book", 35000);
given(productRepository.findById(productId)).willReturn(Optional.of(mockProduct));

// When
ProductDto result = productService.getProduct(productId);

// Then
assertThat(result.getName()).isEqualTo("Spring Book");
then(productRepository).should(times(1)).findById(productId);
}

@Test
@DisplayName("Fetching a non-existent product throws an exception.")
void non_existent_product_throws() {
given(productRepository.findById(anyLong())).willReturn(Optional.empty());
assertThatThrownBy(() -> productService.getProduct(999L))
.isInstanceOf(ProductNotFoundException.class);
}
}

2. ArgumentCaptor — Capturing Method Arguments

Verify exactly what arguments a mocked method was called with.

@Test
@DisplayName("Order creation passes correct data to the event publisher.")
void order_creation_event_verification() {
ArgumentCaptor<OrderCreatedEvent> captor = ArgumentCaptor.forClass(OrderCreatedEvent.class);

orderService.createOrder(new CreateOrderRequest(userId, productId, quantity));

then(eventPublisher).should().publishEvent(captor.capture());
assertThat(captor.getValue().getUserId()).isEqualTo(userId);
assertThat(captor.getValue().getQuantity()).isEqualTo(quantity);
}
Advertisement