Im currently Testing my Controller methods. In one Method I add a Reisepunkt(travelpoint) to a Reise(travel), which is already saved inside a database.
JavaScript
x
private final ReiseRepository repository;
private final ReisepunktRepository reisepunktRepository;
ReiseController(ReiseRepository reiseRepository, ReisepunktRepository reisepunktRepository) {
this.repository = reiseRepository;
this.reisepunktRepository = reisepunktRepository;
}
/**
* Adds a new Reisepunkt to the Reise. Both have to exist in the Database already.
* Will throw a Exception if Reise already contains same Reisepunkt.
* @param idReisepunkt ID of the Reisepunkt.
* @param idReise ID of the Reise.
* @return Configured Reise with new Reisepunkt.
*/
@PutMapping(path = "/reise/reisepunkt/{idReise}")
Reise addReisepunkt(@RequestParam Long idReisepunkt, @PathVariable Long idReise) {
return repository.findById(idReise).map(reise -> {
reisepunktRepository.findById(idReisepunkt).map(reisepunkt -> {
for (int i = 0; i < reise.getReisepunkte().size(); i++) {
if (reisepunkt.getId().equals(reise.getReisepunkte().get(i).getId())) {
throw new IllegalStateException("Reise already contains the Reisepunkt");
}
}
reise.addReisepunkt(reisepunkt);
return reisepunktRepository.save(reisepunkt);
}).orElseThrow(() -> new IllegalStateException("Could not save Reisepunkt"));
return repository.save(reise);
}).orElseThrow(() -> new IllegalStateException("Could not add Reisepunkt to Reise"));
}
Using the generated-request.http API I can use the method to make entrys into the db. Now i wanted to write a test method just so I can get the hang of it.
JavaScript
@Mock
private ReiseRepository reiseRepository;
private ReisepunktRepository reisepunktRepository;
private ReiseController underTest;
@BeforeEach
void setUp() {
underTest = new ReiseController(reiseRepository, reisepunktRepository);
}
@Test
void canAddaReisepunktToReise() {
//given
Reisepunkt reisepunkt = new Reisepunkt(12L, 10.41f, 51.32f,
"nutzer@web.de", "Aussicht");
List<Reisepunkt> reisepunkte = new ArrayList<>();
reisepunkte.add(new Reisepunkt(34L, 4.1f, 32.32f,
"nutzer", "jas"));
List<Reisekatalog> reisekatalogs = new ArrayList<>();
Reise reise = new Reise(new Date(), "TestReise", true,
reisepunkte, reisekatalogs);
long idReise = 1;
long idReisepunkt = 12;
given(reiseRepository.findById(idReise)).willReturn(java.util.Optional.of(reise));
given(reiseRepository.save(reise)).willReturn(reise);
given(reisepunktRepository.findById(idReisepunkt))
.willReturn(java.util.Optional.of(reisepunkt));
given(reisepunktRepository.save(reisepunkt)).willReturn(reisepunkt);
//when
underTest.addReisepunkt(idReisepunkt, idReise);
//then
ArgumentCaptor<Reise> reiseArgumentCaptor = ArgumentCaptor.forClass(Reise.class);
verify(reiseRepository).save(reiseArgumentCaptor.capture());
Reise capturedReise = reiseArgumentCaptor.getValue();
reise.addReisepunkt(reisepunkt);
assertThat(capturedReise).isEqualTo(reise);
}
I always get a NullPointerException in the lines:
JavaScript
given(reisepunktRepository.findById(idReisepunkt))
.willReturn(java.util.Optional.of(reisepunkt));
given(reisepunktRepository.save(reisepunkt)).willReturn(reisepunkt);
Apperently Mockito has a problem when I map an Optional inside another Optional.map and then use given for the second Repository request. I guess there is some special way to implement the Test methode for a given Repo request inside a Optional map.
Advertisement
Answer
You forgot to mock ReisepunktRepository
and this cause the NullPointerException
Update from
JavaScript
private ReisepunktRepository reisepunktRepository;
To
JavaScript
@Mock
private ReisepunktRepository reisepunktRepository;