单元测试 - 为什么我的单元测试在使用此 finish()、处理程序和线程的代码上失败



这是我正在测试的活动。我希望我能用另一种方式写它,因为我听说使用 thread.sleep 很危险。但我不被允许这样做。

以下是此代码的作用:调用 onCreate 时,MainActivity 暂停几秒钟,然后触发 Activity2

  public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                goToAct2();
            }
        };
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                    handler.sendEmptyMessage(0);
                } catch (InterruptedException e) {}
            }
        }).start();
    }
    private void goToAct2(){
    Intent i = new Intent (this,Activity2.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(i);
    finish();
    }
}

我想测试主活动是否调用了正确的活动(即活动 2)。下面是单元测试代码:

public class MainActivityTest extends
        ActivityInstrumentationTestCase2<MainActivity>
{
    MainActivity activity;
    public MainActivityTest()
    {
        super(MainActivity.class);
    }
    protected void setUp() throws Exception
    {
        super.setUp();
        activity=getActivity();
    }
    @UiThreadTest
    public void testOne()
    {
        ActivityMonitor Act2Monitor = getInstrumentation().addMonitor(Activity2.class.getName(), null, false);  
        getInstrumentation().callActivityOnCreate(activity, null);;
        assertEquals(1, Act2Monitor.getHits());
    }
}

我注意到:

  1. 如果我丢弃处理程序线程部分:

    直接在onCreate()中调用goToAct2(),测试仍然失败。但是如果我在该方法中删除 finish(),测试就会通过。

  2. 如果我保留处理程序线程部分:

    无论我做什么,即使实际活动按预期工作,测试也会不断失败。

引擎盖下发生了什么?以及,如何正确编写可以确认创建 Activity2 的测试?

在应用程序活动代码中,您应该具有如下所示的内容:

Intent i = new Intent(this, SecondActivity.class);
startActivityForResult(i, 1);

在活动 2 中,设置要返回到第一活动的数据。

Intent returnIntent = new Intent();
returnIntent.putExtra("result",result);
setResult(Activity.RESULT_OK,returnIntent);
finish();

然后在主活动中,重写 onActivityResult 方法以处理结果。

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 1) {
        if(resultCode == Activity.RESULT_OK){
            String result=data.getStringExtra("result");
        }
        else {
            //Write your code if there's no result
        }
    }
}

最后,在测试用例中使用类ActivityUnitTestCase并调用isFinishCalled()getFinishedActivityRequest()来检查调用它们的参数。

有关此文档的文档位于:

https://developer.android.com/reference/android/test/ActivityUnitTestCase.html#isFinishCalled()

我无法创建评论,所以我必须将其发布为抱歉。

根据我所读到的内容,您需要在调用 finish() 方法后调用 getActivity()。

这意味着您存储在活动中的实例不是新活动,而是被销毁的实例。我会尝试更改getInstrumentation().callActivityOnCreate(activity,null);to getInstrumentation().callActivityOnCreate(getActivity(), null);这应该返回当前活动,而不是已销毁的活动。

希望对您有所帮助。

最新更新