Vincent Durmont

« Back

February 22, 2014

JSON Mockito matchers

Yesterday, I wrote about custom Mockito matchers and this article is an example of a real usage of these matchers. In my code, I often use wrapper services that call distant APIs. The service builds a JSONObject that will be sent to the server so I need to make sure that it is correct. In order to do that, I need a custom JSON Mockito matcher.

The class UserService will use the class ApiWrapper in order to create a user on a distant account server. Here is the first test I wrote:

@Test
public void test_user_is_posted_to_distant_server() {
// GIVEN
ApiWrapper apiWrapper = mock(ApiWrapper.class);
UserService userService = new UserService(apiWrapper);

User user = new User();
user.setEmail("vdurmont@gmail.com");
user.setName("Vincent DURMONT");

// WHEN
userService.create(user);

// THEN
JSONObject json = new JSONObject();
json.put("email", user.getEmail());
json.put("name", user.getName());

verify(apiWrapper).post(json);
}

But when I run the test, I got this failure:

Argument(s) are different! Wanted:
apiWrapper.post(
{"email":"vdurmont@gmail.com","name":"Vincent DURMONT"}
);
-> at com.github.vdurmont.AppTest.test_user_is_posted_to_distant_server(AppTest.java:34)
Actual invocation has different arguments:
apiWrapper.post(
{"email":"vdurmont@gmail.com","name":"Vincent DURMONT"}
);
-> at com.github.vdurmont.service.UserService.create(UserService.java:18)

/*
I got this failure:

java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:86)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertTrue(Assert.java:52)
at com.github.vdurmont.AppTest.test_json_equals(AppTest.java:25)
*/

This is due to the fact that JSONObject doesn't override the method equals so when Mockito uses the default equals matcher, it fails.

In order to have a simple verification, I wrote 2 custom matchers: one for JSONObject and one for JSONArray.

You can find the code on github.