0

I have following Java code that I want to test. What I am having difficulty is figuring out how do I verify that call to handleAppVersionRequest , actually constructs AppVersionResponse object. Is there any way to do that using Mockito?

Here code is code for method:

class MyClass {
        public void handleAppVersionRequest(String dataStr, 
    final int dataChannelId) {
            String ver = "1.0";
            final AppVersionResponse resp = new AppVersionResponse(ver);
            Timber.d("Sending data %s", resp.toString());
            sendResponse(dataChannelId, getGson().toJson(resp));
        }
}

And here is method for test:

@Test
public void testHandleAppVersionRequest() throws Exception {
    MyClass presenter = Mockito.spy(new MyClass());
    String versionRequestJson = "{\"command\":1}";
    when(presenter.getGson()).thenReturn(gSon);
    presenter.handleAppVersionRequest(versionRequestJson,0);
    // How do I verify that AppResponse object was constructed?
    verify(presenter,times(1)).sendResponse(anyInt(),anyString());
}
Maciej Kowalski
  • 25,605
  • 12
  • 54
  • 63
Subodh Nijsure
  • 3,305
  • 5
  • 26
  • 45

1 Answers1

1

If you must test the creation of the object during a unit test, you can extract a factory, mock it for your test, and then verify that the create method is called on it.

At the same time, consider spending some time looking at some tutorials for Mockito and unit testing in general, like this one. You should choose one class that is going to be the 'system under test'. Don't spy or mock this class! Instead, pass in mocks as dependencies that you will use to test the behaviour of your class.

Here is a factory extracted from your MyClass:

class AppVersionResponseFactory {
    AppVersionResponse create(String version) {
        return new AppVersionResponse(version);
    }
}

Then the refactored version of your class where the dependencies (Gson and the factory) are passed in through the constructor:

class MyClass {

    //dependencies that can now be mocked!
    private final AppVersionResponseFactory appVersionResponseFactory;
    private final Gson gson;

    //pass the mockable dependencies in the constructor of the system under test!
    public MyClass(AppVersionResponseFactory appVersionResponseFactory, Gson gson) {
        this.appVersionResposeFactory = factory;
        this.gson = gson;
    }

    public void handleAppVersionRequest(String dataStr, final int dataChannelId) {
        String ver = "1.0";
        AppVersionResponse resp = AppVersionResponseFactory.create(ver);
        Timber.d("Sending data %s", resp.toString());
        sendResponse(dataChannelId, gson.toJson(resp));
    }
}

Now your test looks something like this:

//mocks
AppVersionResponseFactory mockAppVersionResposeFactory;
Gson mockGson;

//system under test
MyClass myClass;

@Before
public void setUp() {
    mockAppVersionResposeFactory = Mockito.mock(AppVersionResponseFactory.class);
    mockGson = Mockito.mock(Gson.class);
    myClass = new MyClass(mockGson, mockAppVersionResposeFactory);
}

@Test
public void testHandleAppVersionRequest() throws Exception {
    String versionRequestJson = "{\"command\":1}";

    myClass.handleAppVersionRequest(versionRequestJson, 0);

    verify(appVersionResposeFactory).create("1.0");
}

Please note that although your question asks for a way to verify the construction of an object, a better test would probably test the final outcome of that method i.e., that sendResponse was called with the correct dataChannelId and correct JSON. You can use the same techniques in this answer to do that i.e., extracting a dependency (perhaps a ResponseSender?), passing it in the constructor for your MyClass, mocking it in the test, then calling verify on it.

David Rawson
  • 20,912
  • 7
  • 88
  • 124
  • 1
    Thanks David for that suggestion of `sendResponse was called with the correct dataChannelId and correct JSON`. I could add signature check for how sendResponse is invoked, that makes my test more clearer and I don't really have to refactor AppVersionResponse. – Subodh Nijsure Dec 11 '16 at 00:11