4

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) {
        Debugger.out(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}");
    doReturn(json)
            .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 doReturn() is not triggered because new JSONObject() !== new JSONObject().

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

GhostCat
  • 137,827
  • 25
  • 176
  • 248
dogmatic69
  • 7,574
  • 4
  • 31
  • 49

2 Answers2

4

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.
GhostCat
  • 137,827
  • 25
  • 176
  • 248
0

This argThat function can help you.

    private static String eqJson(String expectedJson) {
    return argThat(argument -> {
        try {
            JSONAssert.assertEquals(expectedJson, argument, true);
            return true;
        } catch (JSONException e) {
            return false;
        }
    });
}

Then in your test

    // import
    import org.skyscreamer.jsonassert.JSONAssert;
    import static org.mockito.ArgumentMatchers.argThat;

    // then
    then(mock).should(times(1)).method(eqJson(expectedJson));