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.
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.
@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:
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
private ReisepunktRepository reisepunktRepository;
To
@Mock private ReisepunktRepository reisepunktRepository;