I have a simple spring boot app with controller (example)
@RestController
@RequestMapping("/person")
public class PersonController {
@Autowired
PersonService personService;
@PostMapping
ResponseEntity<Void> createNewMessage(@RequestBody Person itemDto, UriComponentsBuilder uriComponentsBuilder){
final Person itemInfo = personService.createPerson(itemDto)
.orElseThrow(()-> new DuplicateException("ALREADY_EXISTS"));
//NOTE: assume there will be a get end point
UriComponents uriComponents = uriComponentsBuilder.path("/person/find/{id}").buildAndExpand(itemInfo.getId());
return ResponseEntity.created(uriComponents.toUri()).build();
}
}
Goal: To be able to "Unit" test DuplicateException in the endpoint using MockMvc - Mockito - "Arrange using when"
Source: https://github.com/kswat/demo.git
This test fails ( Note If "any" is used the test passes - any(Person.class) ) , but what is wrong?
@Test
void given_exact_person_save() throws Exception {
var inPerson = new Person("First","Last");
when(personService.createPerson(ArgumentMatchers.eq(inPerson))).thenReturn(Optional.of(inPerson));
mockMvc.perform(post("/person")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(inPerson)))
.andExpect(status().isCreated());
}
Service - dummy implementation
@Service
public class PersonService {
public Optional<Person> createPerson(Person itemDto) {
return Optional.empty();
}
}
How to complete my test ?
may be have 2 Arrange statements
when(personService.createPerson(ArgumentMatchers.eq(inPerson))).thenReturn(...);
when(personService.createPerson( any(Person.class)) ).thenReturn(...);
PersonServiceis not mocked; consequently its methods cannot be stubbed b) DoesPersonoverrideequals? If not, it cannot be matched (because it is serialized, then deserialized, resulting in a different instance).