使用 Mockito 测试 Spring ControllerMethod,它使用 Optional.map NullPOinterException 更改数据库中的条目
Testing a Spring ControllerMethod using Mockito which alters an entry in the db with Optional.map NullPOinterException
我目前正在测试我的控制器方法。在一种方法中,我将 Reisepunkt(travelpoint) 添加到已经保存在数据库中的 Reise(travel)。
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"));
}
使用生成的-request.http API 我可以使用该方法进入数据库。现在我想写一个测试方法,这样我就可以掌握它了。
@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);
}
我总是在行中得到 NullPointerException:
given(reisepunktRepository.findById(idReisepunkt))
.willReturn(java.util.Optional.of(reisepunkt));
given(reisepunktRepository.save(reisepunkt)).willReturn(reisepunkt);
当我在另一个 Optional.map 中映射一个 Optional 然后将 given 用于第二个 Repository 请求时,Mockito 显然有问题。我想有一些特殊的方法可以在可选映射中为给定的 Repo 请求实现测试方法。
您忘记模拟 ReisepunktRepository
,这导致 NullPointerException
更新自
private ReisepunktRepository reisepunktRepository;
到
@Mock
private ReisepunktRepository reisepunktRepository;
我目前正在测试我的控制器方法。在一种方法中,我将 Reisepunkt(travelpoint) 添加到已经保存在数据库中的 Reise(travel)。
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"));
}
使用生成的-request.http API 我可以使用该方法进入数据库。现在我想写一个测试方法,这样我就可以掌握它了。
@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);
}
我总是在行中得到 NullPointerException:
given(reisepunktRepository.findById(idReisepunkt))
.willReturn(java.util.Optional.of(reisepunkt));
given(reisepunktRepository.save(reisepunkt)).willReturn(reisepunkt);
当我在另一个 Optional.map 中映射一个 Optional 然后将 given 用于第二个 Repository 请求时,Mockito 显然有问题。我想有一些特殊的方法可以在可选映射中为给定的 Repo 请求实现测试方法。
您忘记模拟 ReisepunktRepository
,这导致 NullPointerException
更新自
private ReisepunktRepository reisepunktRepository;
到
@Mock
private ReisepunktRepository reisepunktRepository;