การเรียกใช้ Instrumentation ล้มเหลวเนื่องจาก 'java.lang.NullPointerException'

ฉันกำลังพยายามเขียนกรณีทดสอบหน่วยสำหรับกิจกรรมในแอปของฉันโดยขยายคลาสการทดสอบด้วย ActivityUnitTestCase ฉันสามารถรันกรณีทดสอบได้สำเร็จก่อนหน้านี้ แต่ตอนนี้ฉันได้รับข้อยกเว้นเสมอในขณะที่ใช้งาน แม้ว่าฉันจะค่อนข้างคุ้นเคยกับการจัดการ NullPointerExceptions แต่ฉันก็ไม่สามารถเข้าใจปัญหาที่ทำให้เกิดสิ่งนี้ได้ ฉันไม่พบคำถามที่คล้ายกัน ดังนั้นฉันจึงโพสต์คำถามนี้

การติดตามสแต็กแสดงให้ฉันเห็นว่ามีการอ้างอิงออบเจ็กต์ null ที่บรรทัดนี้ในโค้ดของฉัน

activity = startActivity(mIntent, null, null);

แต่วิธี startActivity ควรได้รับอินสแตนซ์ของกิจกรรมที่ฉันกำลังทดสอบ ฉันไม่แน่ใจว่าทำไมมันกลับเป็นโมฆะ

นี่คือการติดตามสแต็ก

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'

นี่คือชั้นเรียนทดสอบ

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());
    }
}

comment
@Marcin นี่ไม่ได้เป็นเพียงการซ้ำกัน ฉันได้พยายามที่จะแก้ไขจุดบกพร่องแต่ไม่มีเบาะแสและไม่พบคำถามที่เกี่ยวข้อง ดังนั้นฉันจึงได้โพสต์ไว้อย่างหนึ่ง   -  person Prudhvi    schedule 10.08.2015
comment
ฉันยอมรับว่านี่ไม่ใช่กรณี NullPointerException ธรรมดา ข้อยกเว้นถูกส่งมาจากภายในสายการเรียกของคลาส ActivityUnitTestCase ของ Android   -  person Vito Andolini    schedule 11.08.2015
comment
@prudnvi ฉันได้รับข้อยกเว้นเดียวกันในกรณีทดสอบที่คล้ายกันที่ฉันเขียน ฉันกำลังทำการทดสอบบนอุปกรณ์ Lollipop ฉันเพิ่งทำการทดสอบบน KitKat และการทดสอบก็สำเร็จ คุณใช้นักวิ่งทดสอบอะไร? ฉันใช้ GoogleInstrumentationTestRunner ฉันสงสัยว่าเราจำเป็นต้องอัปเกรดเป็นนักวิ่งทดสอบใหม่หรือไม่: AndroidJUnitRunner ซึ่งอยู่ใน SDK เวอร์ชันที่ใหม่กว่า   -  person Vito Andolini    schedule 11.08.2015
comment
@Marcin คุณช่วยยกเลิกการทำเครื่องหมายว่าซ้ำกันได้ไหม ฉันคิดว่ามันไม่แน่นอนที่สุด   -  person Vito Andolini    schedule 11.08.2015
comment
@VitoAndolini ฉันสามารถเรียกใช้กรณีทดสอบเหล่านี้ในโปรแกรมจำลอง Nexus_5_API_22_x86 (Lollipop) ได้สำเร็จโดยมีและไม่มีการใช้ AndroidJUnitRunner แต่กรณีทดสอบล้มเหลวในโปรแกรมจำลอง Nexus_4_API_19 (Kitkat) และบนอุปกรณ์ Samsung S6 (ทั้งสองมีข้อยกเว้นที่แตกต่างกัน) S6 กำลังขว้าง NPE   -  person Prudhvi    schedule 11.08.2015
comment
ฉันมีปัญหาเดียวกัน ActivityUnitTestCase ส่งต่อไปยังอุปกรณ์ทั้งหมดของฉัน ยกเว้น Samsung S5 ที่มี Lollipop   -  person uncle_tex    schedule 20.10.2015


คำตอบ (4)


@prudhvi ฉันไม่คิดว่าฉันมีกระสุนเงิน แต่น่าเสียดาย แต่ฉันขอแนะนำให้ลองติดตาม ขั้นตอนเหล่านี้เพื่ออัปเกรดเป็นไลบรารีสนับสนุนการทดสอบใหม่ใน SDK เวอร์ชันใหม่กว่า ขออภัยที่ไม่สามารถช่วยได้มากกว่านี้!

person Vito Andolini    schedule 11.08.2015

ฉันมีปัญหาเดียวกัน วิธีแก้ไขคือทำการทดสอบ ActivityInstrumentationTestCase2 แทนที่จะเป็น ActivityUnitTestCase และให้กิจกรรมสร้างขึ้นสำหรับฉันในเบื้องหลัง

person Catalin    schedule 23.10.2015

มีโอกาสที่ดีบางอย่างในคลาสแอปพลิเคชันของคุณ (เช่น X ขยายแอปพลิเคชัน) ขัดข้องตั้งแต่เนิ่นๆ หากเป็นกรณีนี้ คุณจะเห็นข้อผิดพลาดนี้.... ชำระเงิน Logcat ของคุณเพื่อดูร่องรอย

person steineron    schedule 26.11.2015

ฉันเปลี่ยน ActivityUnitTestCase เป็น ActivityInstrumentationTestCase2 และลบการเรียก startActivity() ของฉัน (ดูเหมือนว่า ActivityInstrumentationTestCase2 เริ่มกิจกรรมโดยอัตโนมัติ) ตอนนี้มันทำงานอีกครั้ง

person wutzebaer    schedule 31.03.2016