Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android testcase wait for callback

Tags:

android

I'm testing my service class that gets some ip on the internet. I've wrote my tests like this:

    TestTryoutTestService webServices = new TestTryoutTestService(ENDPOINTESTURL);
    TestService adapter = webServices.getWebservice();
    adapter.getIpAsync(mCallback);
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    assertEquals("IP is not equal", result, "1");
}

Callback<TestResponse> mCallback = new Callback<TestResponse>() {
    @Override
    public void success(TestResponse testResponse, Response response) {
        result = testResponse.getIp();
    }

    @Override
    public void failure(RetrofitError error) {
        fail();
    }
};

The problem is that my Thread.sleep is to short and I think it's ugly. So My question is how can I wait in a testcase for a result in a callback?

EDIT:

The tests are runned with robolectric. Even with a thread sleep 10000 it nevers comes in the callback. The http is stubbed via wireframe and it works if it's not done async.

    stubFor(get(urlMatching("/ip/.*"))
            .atPriority(5)
            .willReturn(aResponse()
                            .withStatus(200)
                            .withBodyFile("ip_response.json")
            ));
like image 993
user1007522 Avatar asked Oct 20 '25 02:10

user1007522


1 Answers

You can use a Countdown Latch to do this

CountDownLatch latch = new CountDownLatch(1);

{
    ...
    TestTryoutTestService webServices = new TestTryoutTestService(ENDPOINTESTURL);
    TestService adapter = webServices.getWebservice();
    adapter.getIpAsync(mCallback);
    latch.await(2000, TimeUnit.MILLISECONDS);
    assertEquals("IP is not equal", result, "1");
}

Callback<TestResponse> mCallback = new Callback<TestResponse>() {
    @Override
    public void success(TestResponse testResponse, Response response) {
        result = testResponse.getIp();
        latch.countDown();
    }

    @Override
    public void failure(RetrofitError error) {
        fail();
    }
};

Make sure your result is declared volatile or you might not see the change across threads. For more complex problems consider using a Future (see also it's FutureTask impl), which will take care of thread visibility issues for you as it returns the result to the calling thread.

Edit: Regarding your update, is it not entering the callback for sure, or just not updating the result? Try making it volatile as above, also add logging/breakpoint to check for the callback being entered.

like image 188
Toby Shepheard Avatar answered Oct 22 '25 15:10

Toby Shepheard



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!