11

I am trying to write Unit test cases for Activities in my app by extending the test class with ActivityUnitTestCase. I could successfully run the test cases earlier but now I'm always getting the exception while running them. Even though I'm pretty familiar with handling NullPointerExceptions, I couldn't figure out the problem that's causing this. I couldn't find any similar questions so I'm posting this one.

Stack trace shows me there is a null object reference at this line in my code

activity = startActivity(mIntent, null, null);

But the startActivity method is supposed to get the instance of the activity I'm testing. I'm not sure why it's returning null.

Here is the Stack trace.

java.lang.NullPointerException: Attempt to write to field 'android.os.IBinder android.app.ActivityThread.mLastIntendedActivityToken' on a null object reference
at android.app.Activity.performCreate(Activity.java:6372)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.support.test.runner.MonitoringInstrumentation.callActivityOnCreate(MonitoringInstrumentation.java:346)
at android.test.ActivityUnitTestCase.startActivity(ActivityUnitTestCase.java:158)
at com.abc.test.MainActivityTest.access$100(MainActivityTest.java:16)
at com.abc.test.MainActivityTest$1.run(MainActivityTest.java:34)
at android.app.Instrumentation$SyncRunnable.run(Instrumentation.java:1891)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6117)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)

Test running failed: Instrumentation run failed due to 'java.lang.NullPointerException'

Here is the Test class

public class MainActivityTest extends ActivityUnitTestCase<MainActivity>{

    private Intent mIntent;
    private MainActivity activity;

    public MainActivityTest() {
        super(MainActivity.class);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        //Create an intent to launch target Activity as it is not automatically started by Android Instrumentation
        mIntent = new Intent(getInstrumentation().getContext(), MainActivity.class);
        //Start the activity under test in isolation, in the main thread to avoid assertion error.
        getInstrumentation().runOnMainSync(new Runnable() {
            @Override
            public void run() {
                activity = startActivity(mIntent, null, null);
            }
        });
    }

    @Override
    protected void tearDown() throws Exception {
        super.tearDown();
    }

    /**
     * Tests the preconditions of this test fixture.
     */
    @SmallTest
    public void testPreconditions() {
        assertNotNull("MainActivity is null", getActivity());
    }

    @MediumTest
    public void testSecondActivityWasLaunchedWithIntent() {
        // Get the intent for the next started activity
        final Intent launchIntent = getStartedActivityIntent();
        //Verify the intent was not null.
        assertNotNull("Intent was null", launchIntent);
        //Verify that LaunchActivity was finished
        assertTrue(isFinishCalled());
    }
}
Prudhvi
  • 2,108
  • 7
  • 31
  • 51
  • 1
    @Marcin This is not a mere duplicate. I have tried to debug but no clues and also couldn't find any related questions. So I have posted one. – Prudhvi Aug 10 '15 at 18:09
  • 1
    I agree, this is not a simple NullPointerException case. The exception is thrown from within the call chain of Android's ActivityUnitTestCase class. – Vito Andolini Aug 10 '15 at 22:22
  • @prudnvi I got the same exception in an similar test case I wrote. I was running the test on a Lollipop device. I just ran the test on KitKat, and the test ran successfully. What test runner are you using? I am using GoogleInstrumentationTestRunner. I am wondering if we need to upgrade to the new test runner: AndroidJUnitRunner which is in newer versions of the SDK. – Vito Andolini Aug 10 '15 at 22:31
  • @Marcin can you please unmark this as a duplicate? I think it's most certainly not. – Vito Andolini Aug 10 '15 at 22:33
  • @VitoAndolini I could successfully run these test cases in Nexus_5_API_22_x86 emulator (Lollipop) with and without using AndroidJUnitRunner. But the test cases fail in Nexus_4_API_19 (Kitkat) emulator and also on the Samsung S6 device. (Both of them are throwing different exceptions though). S6 is throwing NPE. – Prudhvi Aug 11 '15 at 01:58
  • I'm having the same issue. ActivityUnitTestCase passes on all my devices except the Samsung S5 with Lollipop. – uncle_tex Oct 19 '15 at 21:02

4 Answers4

0

@prudhvi I don't think I have a silver bullet, unfortunately, but I would suggest trying to follow these steps to upgrade to the new test support libraries in the newer versions of the SDK. Sorry that I can't be of more help!

Vito Andolini
  • 425
  • 5
  • 14
0

I had the same issue. The solution was to make the test an ActivityInstrumentationTestCase2 instead of an ActivityUnitTestCase, and have the activity created for me in the background

Catalin
  • 109
  • 1
  • 1
0

There's a good chance something in your application class (i.e. X extends Application) is crashing early on. If that's the case you'll see this error.... Checkout your logcat for traces.

Mogsdad
  • 40,814
  • 19
  • 140
  • 246
steineron
  • 359
  • 3
  • 5
0

i changed ActivityUnitTestCase to ActivityInstrumentationTestCase2 and removed my startActivity() calls (seems that ActivityInstrumentationTestCase2 automatically starts the activity) now it runs again

wutzebaer
  • 12,445
  • 18
  • 77
  • 144