samedi 2 novembre 2019

mockmvc access to real instance of requstbody

I want to test this function :

@PreAuthorize( "hasRole(@roles.VET_ADMIN)" )
@RequestMapping(value = "/{vetId}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<Vet> updateVet(@PathVariable("vetId") int vetId, @RequestBody @Valid Vet vet, BindingResult bindingResult){
    BindingErrorsResponse errors = new BindingErrorsResponse();
    HttpHeaders headers = new HttpHeaders();
    if(bindingResult.hasErrors() || (vet == null)){
        errors.addAllErrors(bindingResult);
        headers.add("errors", errors.toJSON());
        return new ResponseEntity<Vet>(headers, HttpStatus.BAD_REQUEST);
    }
    Vet currentVet = this.clinicService.findVetById(vetId);
    if(currentVet == null){
        return new ResponseEntity<Vet>(HttpStatus.NOT_FOUND);
    }
    currentVet.setFirstName(vet.getFirstName());
    currentVet.setLastName(vet.getLastName());
    currentVet.clearSpecialties();
    for(Specialty spec : vet.getSpecialties()) {
        currentVet.addSpecialty(spec);
    }
    this.clinicService.saveVet(currentVet);
    return new ResponseEntity<Vet>(currentVet, HttpStatus.NO_CONTENT);
}

This is my test class and here is a example of a test on this function:

@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=ApplicationTestConfig.class)
@WebAppConfiguration
public class VetRestControllerTests {

@Autowired
private VetRestController vetRestController;

@MockBean
private ClinicService clinicService;

private MockMvc mockMvc;

private List<Vet> vets;
@Before
public void initVets(){
    this.mockMvc = MockMvcBuilders.standaloneSetup(vetRestController)
            .setControllerAdvice(new ExceptionControllerAdvice())
            .build();
    vets = new ArrayList<Vet>();
    specialties= new ArrayList<Specialty>();
    Specialty spec1=new Specialty();
    specialties.add(spec1);
    Specialty spec2=new Specialty();
    specialties.add(spec2);


    Vet vet = new Vet();
    vet.setId(1);
    vet.setFirstName("James");
    vet.setLastName("Carter");
    vets.add(vet);

    vet = new Vet();
    vet.setId(2);
    vet.setFirstName("Helen");
    vet.setLastName("Leary");
    vets.add(vet);

    vet = new Vet();
    vet.setId(3);
    vet.setFirstName("Linda");
    vet.setLastName("Douglas");
    vets.add(vet);
}


 @Test
@WithMockUser(roles="VET_ADMIN")
public void testUpdateVetSuccess() throws Exception {
    given(this.clinicService.findVetById(1)).willReturn(vets.get(0));
    Vet newVet = vets.get(0);
    newVet.setFirstName("James");
    ObjectMapper mapper = new ObjectMapper();
    String newVetAsJSON = mapper.writeValueAsString(newVet);
    this.mockMvc.perform(put("/api/vets/1")
        .content(newVetAsJSON).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
        .andExpect(content().contentType("application/json;charset=UTF-8"))
        .andExpect(status().isNoContent());

    this.mockMvc.perform(get("/api/vets/1")
        .accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON_VALUE))
        .andExpect(status().isOk())
        .andExpect(content().contentType("application/json;charset=UTF-8"))
        .andExpect(jsonPath("$.id").value(1))
        .andExpect(jsonPath("$.firstName").value("James"));
}

Now I want to write a test for testing this part of my code in updateVet:

for(Specialty spec : vet.getSpecialties()) {
    currentVet.addSpecialty(spec);
}

but I don't know how can I mock getSpecialties() for vet. I don't have access to this object inside my test method. I try a mock vet instead of newVet. but then I get this error because I can't use mapper and writeValueAsString for a mock object.

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.mockito.internal.debugging.LocationImpl and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: org.springframework.samples.petclinic.model.Vet$MockitoMock$1652139046["mockitoInterceptor"]->org.mockito.internal.creation.bytebuddy.MockMethodInterceptor["mockHandler"]->org.mockito.internal.handler.InvocationNotifierHandler["invocationContainer"]->org.mockito.internal.stubbing.InvocationContainerImpl["invocationForStubbing"]->org.mockito.internal.invocation.InvocationMatcher["invocation"]->org.mockito.internal.invocation.InterceptedInvocation["location"])

so, how can I test getSpecialties() inside update function?

Aucun commentaire:

Enregistrer un commentaire