【问题标题】:unit test - why does my unit test fail on this code that uses finish(), handler, and thread?单元测试 - 为什么我的单元测试在使用 finish()、处理程序和线程的代码上失败?
【发布时间】:2016-07-14 01:53:32
【问题描述】:

这是我正在测试的活动。 我希望我可以用另一种方式写它,因为我听说使用 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. 如果我保留处理程序线程部分:

    无论我做什么,测试总是失败,即使实际活动按预期工作。

幕后发生了什么?还有,如何正确编写可以确认 Activity2 创建的测试?

【问题讨论】:

  • 你不应该在assertEquals()之前等待3秒吗?
  • 也试过了。测试仍然没有通过。
  • 删除了finish() 并尝试等待?您可能需要等待 3 秒多一点。大概 4 秒。
  • 也试过了。我等了 10 秒,而不是 3 或 4 秒。不允许删除 finish()。

标签: java android multithreading unit-testing


【解决方案1】:

在您的应用程序活动代码中,您应该有这样的内容:

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

然后在主activity中,重写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()

【讨论】:

  • 恐怕这不是我要找的,因为我无法更改活动的源代码。
  • 好的,你应该仍然可以使用 ActivityUnitTestCase 和 isFinishCalled() 方法。
  • 它们无助于验证 Activity2 的创建。也许我错过了什么,你能详细说明一下吗?
  • 你看过ActivityUnitTestCase吗?以下 URL 的代码 sn-p 显示了如何获取子活动的实例。 stackoverflow.com/questions/9643260/…获取子Activity的实例(这本身就是它被创建的证明)并使用ActivityTestCase查询它以获取确认信息。
【解决方案2】:

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

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

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

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    相关资源
    最近更新 更多