0

I am trying to do testing for my mvc controllers so I know they are working properly. I will post all the code first and then explain what is happening:

My Controller

@RequestMapping(value ="Residents/create", method=RequestMethod.POST)
public ResponseEntity<Object> createNewResident(@RequestBody Resident 
resident){
    Apartment apartment = apartmentService.findByApartmentId(167);
    resident.setApartment(apartment);
    System.out.println("slack api");

    String requestUrl = "SlackStringThatIChanged" +"&email=" +resident.getEmail() +
    "&first_name=" + resident.getFirstName() + "&last_name=" + resident.getLastName();
    try {
    URL url = new URL(requestUrl);
    HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
    httpCon.setDoOutput(true);
    httpCon.setRequestMethod("GET");

    //View Slack response
    /*BufferedReader br = new BufferedReader(new InputStreamReader(httpCon.getInputStream()));
    StringBuilder sb = new StringBuilder();
    String line;
    while ((line = br.readLine()) != null) {
        sb.append(line + "\n");
        System.out.println(line);
    }
    br.close();
    */
    } catch (ProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return ResponseEntity.ok(residentService.createResident(resident) );
}

My Test method

@Test//this still has problems with the apartment...
public void createNewResidentTest() throws Exception {

    apartmentComplex = new ApartmentComplex();
    apartmentComplex.setComplexId(1);
    apartmentComplex.setAddress("1234 theAddress");
    apartmentComplex.setEmail("some@email.com");
    apartmentComplex.setName("westerly");
    apartmentComplex.setPhone("8548");
    apartmentComplex.setWebsite("www.serwtet.com");
    apartmentComplex.setPhoto("weewtfsw");


    apartment = new Apartment();
    apartment.setApartmentId(1);
    apartment.setApartmentNumber(101);
    apartment.setCapacity(6);
    apartment.setOccupancy(3);

    List<Apartment> apt = new ArrayList<>();
    apt.add(apartment);
    apartmentComplex.setApartments(apt);


    resident = new Resident();
    resident.setResidentId(1);
    resident.setFirstName("Cool");
    resident.setLastName("Man");
    resident.setEmail("coolman@cool.com");
    resident.setPhone("548791234");
    resident.setSlackId("32f4443rwd");
    resident.setAbout("Yeah boi");
    resident.setApartment(apartment);

    Set<Resident> resLis = new HashSet<Resident>();
    resLis.add(resident);
    apartment.setResidents(resLis);

    mvc.perform(MockMvcRequestBuilders.post("http://localhost:8181/api/Residents/create", resident)
            .accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk());
}

So, I am trying to test that controller that creates a resident. I was first getting an error that said something like "reference is nullpointerexception" which I figured out it was due that resident is staying in an apartment and an apartment exist in the apartment complex. After fixing this error I stumble upon "Status excepted <200> but was <400>" and in the console output I get this:

MockHttpServletRequest:
  HTTP Method = POST
  Request URI = /api/Residents/create
   Parameters = {}
      Headers = {Accept=[application/json]}

Handler:
         Type = com.application.controller.ResidentController
       Method = public org.springframework.http.ResponseEntity<java.lang.Object> com.application.controller.ResidentController.createNewResident(com.application.model.Resident)

Async:
Async started = false
 Async result = null

Resolved Exception:
         Type = org.springframework.http.converter.HttpMessageNotReadableException

ModelAndView:
    View name = null
         View = null
        Model = null

FlashMap:
   Attributes = null

I really don't know what is happening or what could be the problem. Maybe I am implementing the test wrong?

Please let me know any thought you have! Thank you.

SkiiNet
  • 67
  • 1
  • 8
  • 1
    Is your Controller class annotated with RequestMapping(value="api") ? – Panayiotis Poularakis Aug 30 '17 at 16:30
  • Per MockMvcRequestBuilders, second parameter of post is uriVars - zero or more URI variables – Sean Carroll Aug 30 '17 at 16:47
  • Its throwing org.springframework.http.converter.HttpMessageNotReadableException, Do you have jackson api library in your dependencies and is Resident class property annotated with JSON annotation. Using Fiddler check whats going in the body of your request, it seems body is not the same which your controller is expecting. – Amit K Bist Aug 30 '17 at 16:48
  • yes, I am doing every controller through api/*, @SeanCarroll, can you give me an example of the uriVars? I was reading the documentation but I didn't understood what was supposed to be there. I have the json dependency in my pom. I used post man to test the controller and it is showing the json with all the values that I am passing. – SkiiNet Aug 30 '17 at 17:21
  • Your route doesn't have any UriVariables so nothing needs to go there. You should be passing your json using the content method off of MockHttpServletRequestBuilder – Sean Carroll Aug 30 '17 at 17:24
  • I have another test that has uri variables, could you explain them to me? – SkiiNet Aug 30 '17 at 18:13
  • If your request mapping is something like /Residents/{id} then in the mockmvc get/post you would pass in the id as a uri variable. For example MockMvcRequestBuilders.post("/api/Residents/{id}", residentId) – Sean Carroll Aug 30 '17 at 19:16
  • ah i see, that is how it is used, thanks! – SkiiNet Aug 30 '17 at 19:33

1 Answers1

0

What about something like the following?

@Test//this still has problems with the apartment...
public void createNewResidentTest() throws Exception {

    Resident resident = new Resident();
    // build resident
    // convert to json string
    mvc.perform(MockMvcRequestBuilders.post("/api/Residents/create")
            .contentType(MediaType.APPLICATION_JSON)
            .content(json)
            .accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk());
}
Sean Carroll
  • 2,651
  • 2
  • 24
  • 21
  • I tried it but it didn't work, instead, i am now doing .param() and i was able to populate the body – SkiiNet Aug 30 '17 at 18:38
  • so, i think the content() doesn't put anything in the parameters – SkiiNet Aug 30 '17 at 19:33
  • @SkiiNet, what do you mean by parameters? This works for me but I did alter the request mapping to include consumes = {MediaType.APPLICATION_JSON_UTF8_VALUE} – Sean Carroll Aug 30 '17 at 20:01
  • the .content(json) doesn't show in the parameters MockHttpServletRequest: HTTP Method = POST Request URI = /api/Residents/create Parameters = {} Headers = {Accept=[application/json]} – SkiiNet Aug 30 '17 at 20:37
  • I'm not sure its suppose to. In my test you're right it doesn't however it still populates the resident parameter appropriately – Sean Carroll Aug 30 '17 at 20:44