使用espresso时,setContentView可以被android-annotations取代吗?

时间:2017-10-28 21:30:34

标签: android android-espresso android-annotations

我有espresso测试,用于验证是否显示文字:

public class InformationActivityTests {
    @Rule
    public ActivityTestRule<InformationActivity_> mInformationActivityTestRule =
            new ActivityTestRule<InformationActivity_>(InformationActivity_.class) {
                @Override
                protected Intent getActivityIntent() {
                    Intent i = new Intent(getTargetContext(), InformationActivity_.class);
                    i.putExtra("INFORMATION", "Espresso");
                    return i;
                }
            };

    @Test
    public void textIsDisplayed() {
        onView(withText("Espresso")).check(matches(isDisplayed()));
    }
}

当Activity有以下代码时,此测试传递

@EActivity
public class InformationActivity extends AppCompatActivity {
    @ViewById(R.id.information_view)
    TextView informationView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_information);

        Intent intent = getIntent();
        String information = intent.getStringExtra("INFORMATION");
        informationView.setText(information);
    }
}

失败当我将setContentView“移动”到@EActivity注释时:

@EActivity(R.layout.activity_information)
public class InformationActivity extends AppCompatActivity {
    @ViewById(R.id.information_view)
    TextView informationView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = getIntent();
        String information = intent.getStringExtra("INFORMATION");
        informationView.setText(information);
    }
}

错误是:

  

java.lang.RuntimeException:无法启动活动ComponentInfo {com.edu/com.edu.InformationActivity_}:java.lang.NullPointerException:尝试调用虚方法'void android.widget.TextView.setText(java.lang .CharSequence)'对空对象引用

我做错了什么或是espresso / android-annotations的问题?

2 个答案:

答案 0 :(得分:1)

我在使用@EActivity(R.layout.activity_information)时检查了android-annotations生成的代码,这就是onCreate在生成的类(InformationActivity _)中的样子:

public void onCreate(Bundle savedInstanceState) {
    OnViewChangedNotifier previousNotifier = OnViewChangedNotifier.replaceNotifier(onViewChangedNotifier_);
    init_(savedInstanceState);
    super.onCreate(savedInstanceState);
    OnViewChangedNotifier.replaceNotifier(previousNotifier);
    setContentView(R.layout.activity_information);
}

问题是它首先调用 super.onCreate (所以onCreate from InformationActivity)我处理intent和TextView,然后调用 setContentView ,这不能正常工作那样的。

这个问题的解决方案是Be_Negative建议的,所以使用@AfterViews注释。它还简化了一些代码(我可以删除onCreate方法):

@EActivity(R.layout.activity_information)
public class InformationActivity extends AppCompatActivity {
    @ViewById(R.id.information_view)
    TextView informationView;

    @AfterViews
    void handleIntent() {
        Intent intent = getIntent();
        String information = intent.getStringExtra("INFORMATION");
        informationView.setText(information);
    }    
}

答案 1 :(得分:0)

您的问题是您永远不会初始化信息视图

public class InformationActivity extends AppCompatActivity {
@ViewById(R.id.information_view)
TextView informationView; //<-- Null

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent intent = getIntent();
    String information = intent.getStringExtra("INFORMATION");
    informationView.setText(information); //<--STILL NULL
}
}

因此,您首先必须初始化该视图。