在Android上导致NPE的runOnUiThread和sendKeys调用的序列

时间:2013-02-14 12:32:28

标签: java junit nullpointerexception android-testing

我是Android和JUnit测试的新手。 我试图为MyFirstApp示例提出一些测试用例,如下所述: http://developer.android.com/training/basics/firstapp/index.html

以下是我的测试类的样子:

@Override
protected void setUp() throws Exception {
    // TODO Auto-generated method stub
    super.setUp();
    setActivityInitialTouchMode(false);

    mainActivity = (MainActivity)getActivity();

    editText = (EditText) mainActivity.findViewById(
                             com.example.myfirstapp.R.id.edit_message);
    button = (Button) mainActivity.findViewById(
                             com.example.myfirstapp.R.id.button1);

}

public void testPreconditions(){
    assertTrue(editText.getHint().toString().equals(
                  mainActivity.getString(
                      com.example.myfirstapp.R.string.edit_message)));
}


public void testUI(){
    mainActivity.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            editText.performClick();

        }
    });
    getInstrumentation().waitForIdleSync();

    this.sendKeys(KeyEvent.KEYCODE_A);
    this.sendKeys(KeyEvent.KEYCODE_B);
    this.sendKeys(KeyEvent.KEYCODE_C);
    this.sendKeys(KeyEvent.KEYCODE_D);
    this.sendKeys(KeyEvent.KEYCODE_E);



    mainActivity.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            button.performClick();

        }
    });
}

testPrecontions测试成功。然而,这给了NPE“button.performClick();”

有人可以指出我可能做错了吗?

由于 -Angshu

2 个答案:

答案 0 :(得分:2)

好的,我想在第二次runOnUiThread调用后需要在getInstrumentation().waitForIdleSync()之后添加调用,如下所示

public void testUI(){

    mainActivity.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            editText.performClick();

        }
    });

    this.sendKeys(KeyEvent.KEYCODE_A);
    this.sendKeys(KeyEvent.KEYCODE_B);
    this.sendKeys(KeyEvent.KEYCODE_C);
    this.sendKeys(KeyEvent.KEYCODE_D);
    this.sendKeys(KeyEvent.KEYCODE_E);



    mainActivity.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            button.performClick();

        }
    });
    getInstrumentation().waitForIdleSync();
}

希望这有助于其他人陷入类似情况。

谢谢大家! -Angshu

答案 1 :(得分:0)

该按钮没有已分配的ID,因此#findViewByID会返回null,您无法在performClick()上致电null-Object

这应该是你的GUI声明(从教程中复制),对吗?

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
    <EditText android:id="@+id/edit_message"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:hint="@string/edit_message" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_send" />
</LinearLayout>

添加Button的ID属性,就像EditText一样,这应该修复View查找的错误:

<Button android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button_send" />