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

时间:2016-07-14 01:53:33

标签: java android multithreading unit-testing

这是我正在测试的活动。 我希望我能用另一种方式写它,因为我听说使用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();
    }
}

我想测试MainActivity是否调用了正确的Activity(即Activity2)。这是单元测试代码:

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. 如果我保留处理程序 - 线程部分:

    无论我做什么,即使实际活动按预期进行,测试也会继续失败。

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

2 个答案:

答案 0 :(得分:0)

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

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

在activity2中设置要返回FirstActivity的数据。

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

答案 1 :(得分:0)

我无法创建评论,因此我必须将此发布为asnwer抱歉。

根据我的阅读,你需要在调用finish()方法之后调用getActivity()。

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

希望它有所帮助。