j2emanue
j2emanue

Reputation: 62519

Mockito - how to trigger a call from a mocked call?

I've looked over this post but still confused. What i want to do is that when i call my mocked service i want another method to be called. Specifically let me show you the class i am mocking (and keep in mind i am trying to test a presenter class if that matters):

Here is the NewsService class i am mocking:

    public class NewsService implements INewsServiceContract {

    Gson gson;
    Callback mCallback;


    public NewsService() {
        configureGson();
    }

    private static String readStream(InputStream in) {
        StringBuilder sb = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(in));) {

            String nextLine = "";
            while ((nextLine = reader.readLine()) != null) {
                sb.append(nextLine);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    public void setCallBack(Callback cb) {
        mCallback = cb; // or we can set up event bus
    }

    private void configureGson() {


        GsonBuilder builder = new GsonBuilder();
        builder.excludeFieldsWithoutExposeAnnotation();
        gson = builder.create();
    }

    @Override
    public void loadResource() {

        new AsyncTask<String, String, String>() {
            @Override
            protected String doInBackground(String... params) {
                String readStream = "";
                try {
                    URL url = new URL("https://api.myjson.com/bins/nl6jh");
                    HttpURLConnection con = (HttpURLConnection) url.openConnection();
                    readStream = readStream(con.getInputStream());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return readStream;
            }

            @Override
            protected void onPostExecute(String result) {
                super.onPostExecute(result);
                NewsService.this.onRequestComplete(result);


            }
        }.execute();
    }

    public void onRequestComplete(String data) {

        data = data.replaceAll("\"multimedia\":\"\"", "\"multimedia\":[]");
        news.agoda.com.sample.Model.NewsEntities newsEntities = gson.fromJson(data, NewsEntities.class);
        mCallback.onResult(newsEntities);
    }
}

its nothing fancy and at the end in onRequestComplete it just makes a call to a listener with the results. the listener is this case is my presenter if that matters.

In my test case i would like to verify that this call back actually took place. I have tried the following test with my mocked service:

        @org.junit.Test
    public void shouldDisplayResultsOnRequestComplete() throws Exception {
        presenter.loadResource();
when(service.loadResource()).thenAnswer(new Answer<Object>() {

    Object answer(InvocationOnMock invocation) {
      //what do i do in here ? 
    }

});
}

all i want to test is that if someone calls service.loadResouces() then they get a call back with the results. can you help ?

Upvotes: 1

Views: 1448

Answers (1)

john16384
john16384

Reputation: 8044

So you have a Presenter, and you want to test if loadResources of NewsService triggers a callback, except... NewsService is not the class being tested here.

The test if loadResources triggers a callback should be in NewsServiceTest.

If you are interested if the Presenter class can deal properly with the callback call, just call it directly and verify how it reacts.

However, if you still want to do this part of the test in the Presenter test case then it's gonna be tricky really.

You would have to first capture the result from the setCallback method so you know where to do your callback -- alternatively, you could assume that this is the Presenter instance.

Then in the Answer from loadResources you will need to simply trigger the callback yourself (which is not much different then doing it directly as I suggested above). This could be as simple as:

presenter.onResult(newsEntities);

...with some sample newsEntitities.

I would recommend strongly against this though as you are basically recreating the behaviour of NewsService in the Answer object.

Here's is how I would test presenter:

presenter.loadResource();

verify(mockNewsService).loadResource();

presenter.onResult(mockedNewsEntities);

// assert/verify if presenter is now in correct state

Upvotes: 1

Related Questions