dogmatic69 dogmatic69 - 3 years ago 122
Java Question

Make mockito less strict with object comparison

I have the following code:

public JSONObject addProductToOrder(int orderId, int productId, String name, double price) {
JSONObject json = new JSONObject();
try {
json.put("orderId", orderId);
json.put("productId", productId);
json.put("name", name);
json.put("price", price);
} catch (JSONException e) {
return this.dataSource.write("/orderItems/addproductToOrder", json);

I want to test so using Mockito and I have done the following:

public void getOrder() throws JSONException {
JSONObject json = new JSONObject("{result: 'OK', error: 0}");
.when(this.clientSpy) // this.clientSpy = Mockito.spy(client);
.post("/orderItems/addProductToOrder", new JSONObject("{productId: 1, orderId: 1, price: 15.99, name: 'Product 1'}"));

OrderItem orderItem = new OrderItem(this.api);
assertEquals("OK", orderItem.addProductToOrder(1, 1, "Product 1", 15.99).get("result"));

The way I understand things, my
is not triggered because
new JSONObject() !== new JSONObject()

Is there a way to make it not compare the objects, but instead just the contents?

Answer Source

What happens here is that Mockito is calling equals() to compare the object that you provided to the specification to the one that is used for the actual method call.

Basically, there are three options:

  • if you just provide an object, equals() is used to compare
  • then you have a variety of other ArgumentMatchers, such as any() or isNull(). Please note: when using such matchers, all arguments must be matched, you can't do: foo(any(), 5) for example.
  • if that doesn't do: you can also use an ArgumentCaptor. Meaning: instead of having Mockito compare objects, you simply record the object that was passed to the mock. And then you add another step in your test case where you check the captured argument as required.
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download