Search code examples
androidunit-testingtestingrobolectricrobolectric-gradle-plugin

How to test ListView items from server using Robolectric 3.0


I am using Robolectric to test my Application. In my app I want to check the listview is there any items in that view. And test the onClickItem from the listview. The listview items is dynamic from server. Every time the activity is started it will request from server. But, Robolectric didn't wait the response, so the adapter on the listview still Null.

@RunWith(CustomRobolectricRunner.class)
@Config(constants = BuildConfig.class, emulateSdk = 19)
public class HomeScreenTest {

    private HomeActivity activity;

    @Before
    public void setUp() {
        activity = Robolectric.setupActivity(HomeActivity.class);
        FakeHttp.getFakeHttpLayer().interceptHttpRequests(true);
        FakeHttp.setDefaultHttpResponse(200, "OK");
        FakeHttpLayer fakeHttpLayer = FakeHttp.getFakeHttpLayer();
        assertFalse(fakeHttpLayer.hasPendingResponses());
        assertFalse(fakeHttpLayer.hasRequestInfos());
        assertFalse(fakeHttpLayer.hasResponseRules());
    }

    @Test
    public void selectItemCategoryMenuShouldStartSearchResultActivity() throws Exception {
        Thread.sleep(5000);
        ListView leftDrawer = (ListView) activity.findViewById(R.id.left_drawer);
        assertThat(leftDrawer).isNotNull();
        leftDrawer.performItemClick(leftDrawer.getAdapter().getView(0, null, null), 0, leftDrawer.getAdapter().getItemId(0));

        Intent intent = shadowOf(activity).peekNextStartedActivity();
        ShadowIntent shadowIntent = shadowOf(intent);
        assertEquals(SearchResultActivity.class.getName(), shadowIntent.getClass().getName());
    }
}

This is the error from the Robolectric test.

Unexpected HTTP call GET http://example.com/api/app/getWallpaper.php HTTP/1.1

java.lang.NullPointerException
    at com.l23rf.android.stockphoto.HomeScreenTest.selectItemCategoryMenuShouldStartSearchResultActivity(HomeScreenTest.java:71)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:235)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:168)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

How to put the Robolectric code to wait the response from server. So the listview adapter is not null anymore, and can test the listview.


Solution

  • I thought you were missplacing the initialization. First you have to set getFakeHttpLayer().interceptHttpRequests(false). Then it should be like this :

    @Before
    public void setUp() {
    
        FakeHttp.getFakeHttpLayer().interceptHttpRequests(false);
        FakeHttp.setDefaultHttpResponse(200, "OK");
        FakeHttpLayer fakeHttpLayer = FakeHttp.getFakeHttpLayer();
        activity = Robolectric.setupActivity(HomeActivity.class);
        assertFalse(fakeHttpLayer.hasPendingResponses());
        assertFalse(fakeHttpLayer.hasRequestInfos());
        assertFalse(fakeHttpLayer.hasResponseRules());
    }
    

    Just tell me once you've done to implement it.