🕐 Tempo di lettura: 2 minuti
Questa volta niente WebFlux: una pillola semplice per chi scrive (o dovrebbe scrivere) test in Java. Quindi, sì, praticamente tutti!
Hai mai voluto verificare cosa viene effettivamente passato a un metodo mockato? Non se è stato chiamato – quello lo fa verify() – ma con quale oggetto, con quali dati?
📑 L'esempio
Nello snippet qui sotto ho usato ArgumentCaptor (lib. Mockito) per intercettare l'oggetto passato a un metodo save(...) su un mock. È uno strumento utile per quei casi in cui vuoi ispezionare il contenuto reale degli oggetti che transitano, appunto, nei tuoi metodi mockati.
@SuppressWarnings("squid:S3577")
class SampleTest016 {
@Getter
@AllArgsConstructor
private static class Car {
private String model;
private int year;
}
private interface CarRepository {
void save(final Car car);
}
@AllArgsConstructor
private static class CarService {
private CarRepository repository;
public void addNewModel(final String model, final int year) {
repository.save(new Car(model, year));
}
}
@Test
void test_addNewModel_savesCarWithCorrectData() {
final CarRepository carRepository = mock(CarRepository.class);
final CarService carService = new CarService(carRepository);
//build a captor to catch Car instances passed to the mock
final ArgumentCaptor<Car> captor = ArgumentCaptor.forClass(Car.class);
carService.addNewModel("Porsche 356A", 1956);
verify(carRepository, times(1)).save(captor.capture()); //capture the argument from the save() method
final Car savedCar = captor.getValue(); //fetch the captured Car object
assertEquals(1956, savedCar.getYear());
assertEquals("Porsche 356A", savedCar.getModel());
}
}
🔍 Come funziona?
- prima si definisce un
ArgumentCaptor<T>passando tra< >il tipo da intercettare (es.ArgumentCaptor<Car>). Se il metodo mockato ha più parametri, puoi creare piùArgumentCaptor, uno per ciascun tipo capture()intercetta l'argomento passato a un metodo mockatogetValue()ti restituisce quell'oggetto per verificarne i valori nelle tue asserzioni
📌 Perché e quando utilizzarlo?
Personalmente non lo vedo usare spesso, ma è un ottimo strumento quando vuoi verificare il contenuto effettivo di un oggetto passato ad un mock ed è altrettanto utile per testare effetti collaterali e interazioni indirette, ad esempio quando un metodo non restituisce nulla ma deve comunque inviare qualcosa a un altro componente!
Alla prossima pillola! ☕