theBigOzzy
theBigOzzy

Reputation: 77

Mockito when returns null when rest call parameter passed in is JSON

I have a piece of code that I want to test which takes a JSON string and uses the object from the JSON string to call a method

@RequestMapping(value = "/cancel", method = RequestMethod.POST, produces = "application/json")
    public ReservationCancelResponseType cancel(@RequestBody CancelReservationRequest request) {
        ReservationCancelResponseType result = null;

        for(BrandEnum brand : request.getBrands()) {
            switch(brand) {
            case BRAND_NAME:
                result = service.cancel(request);
                break;
            }
        }

        return result;
    }

I am trying to call this using the following code

@Test
public void testCancel() throws Exception {
    ReservationCancelResponseType responseType = new ReservationCancelResponseType();

    CancelReservationRequest request = new CancelReservationRequest();
    List<BrandEnum> brands = new ArrayList<>();
    brands.add(BrandEnum.BRAND_NAME);
    request.setBrands(brands);

    String requestString = objectMapper.writeValueAsString(request);

    when(service.cancel(request)).thenReturn(responseType);

    this.mockMvc.perform(post("/cancel")
                .contentType(MediaType.APPLICATION_JSON)
                .content(requestString)
            ).andExpect(status().isOk());
}

I think the reason this is not working is because in the when().thenReturn() call, I am passing in an object but in the rest call I am passing in a String version of this object created by the objectMapper so these are different so I am getting null for the when().thenReturn() call

Is this correct and if so how would you suggest i resolve this?

Upvotes: 1

Views: 2581

Answers (1)

glytching
glytching

Reputation: 48015

Assuming that the instance of service which is used by your controller in the test flow definitely the same instance as you are mocking in your test then the likeliest cause of the issue is CancelReservationRequest's implementation of equals(). Either it has no equals() or its equals() implementation is returning false when Mockito attempts to compare the instance expected by your when/then call with the instance used inside your controller method.

You could verify this by changing ...

when(service.cancel(request)).thenReturn(responseType)

... to :

when(service.cancel(Mockito.any(CancelReservationRequest.cla‌ss))).thenReturn(res‌​ponseType)

If the service.cancel() method returns your response type then you'll know the issue is with CancelReservationRequest's equality check. The fix for this is to implement an equals() method which allows Mockito to correctly compare the instance expected by your when/then call with the instance used inside your controller method. You could even use Mockito.refEq() if creating a custom equals() method is not a runner.

Upvotes: 2

Related Questions