从@UiThreadTest调用waitForMonitorWithTimeout() [英] Call waitForMonitorWithTimeout() from a @UiThreadTest

查看:126
本文介绍了从@UiThreadTest调用waitForMonitorWithTimeout()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要说明我的最新问题,编写JUnit测试我的Andr​​oid应用程序,我写了一个简单的例子,有两个活动, StartActivityForResult ChildActivity 。前者包含了一个的TextView (用于显示目的)和按钮而后者只包含一个按钮。该 onClickListener StartActivityForResult 按钮简单地启动的一个实​​例 ChildActivity

To illustrate my latest problem with writing JUnit tests for my Android app, I wrote a simple example with two activities, StartActivityForResult and ChildActivity. The former contains a TextView (for display purposes) and a Button while the later contains just a Button. The onClickListener for the button in StartActivityForResult simply starts an instance of ChildActivity.

private View.OnClickListener onStart = new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Log.d(TAG, "Start button clicked");
        Intent intent = new Intent(StartActivityForResult.this, ChildActivity.class);

        StartActivityForResult.this.startActivityForResult(intent, R.id.child_request);
    }
};

现在我想使用JUnit测试这个方法。所以我写了下面的测试:

Now I want to test this method using JUnit. So I wrote the following test:

package codeguru.startactivityforresult;

import android.app.Activity;
import android.app.Instrumentation;
import android.content.Intent;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import junit.framework.Assert;

public class StartActivityForResultTest extends ActivityInstrumentationTestCase2<StartActivityForResult> {

    public StartActivityForResultTest() {
        super(StartActivityForResult.class);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();

        Log.d(TAG, "setUp()");

        this.setActivityInitialTouchMode(false);

        this.activity = this.getActivity();
        this.resultText = (TextView) this.activity.findViewById(R.id.result_text);
        this.startButton = (Button) this.activity.findViewById(R.id.start_button);

        Intent data = new Intent();
        data.putExtra(this.activity.getString(R.string.result), RESULT);
        Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, data);

        this.childMonitor = new Instrumentation.ActivityMonitor(ChildActivity.class.getName(), result, true);
        this.getInstrumentation().addMonitor(this.childMonitor);
    }

    @Override
    public void tearDown() throws Exception {
        this.activity.finish();

        super.tearDown();
    }

    @UiThreadTest
    public void testStartButtonOnClick() {
        Assert.assertTrue(this.startButton.performClick());

        Activity childActivity = this.getInstrumentation().waitForMonitorWithTimeout(this.childMonitor, TIME_OUT);
        Assert.assertNotNull(childActivity); // <------ Line 51

        Button resultButton = (Button) childActivity.findViewById(R.id.result_button);
        Assert.assertTrue(resultButton.performClick());

        Assert.assertEquals(Integer.toString(RESULT), this.resultText.getText().toString());
    }
    private Activity activity = null;
    private TextView resultText = null;
    private Button startButton = null;
    private Instrumentation.ActivityMonitor childMonitor = null;
    private static final int TIME_OUT = 5 * 1000; // 5 seconds
    private static final int RESULT = 69;
    private static final String TAG = StartActivityForResultTest.class.getName();
}

运行这个测试提供了以下的输出:

Running this test gives the following output:

codeguru@trolloc:~/src/java/stackoverflow/sscce/StartActivityForResult/test$ adb logcat -c
codeguru@trolloc:~/src/java/stackoverflow/sscce/StartActivityForResult/test$ adb shell am instrument -w -e class codeguru.startactivityforresult.StartActivityForResultTest codeguru.startactivityforresult.tests/android.test.InstrumentationTestRunner

codeguru.startactivityforresult.StartActivityForResultTest:
Failure in testStartButtonOnClick:
junit.framework.AssertionFailedError
    at codeguru.startactivityforresult.StartActivityForResultTest.testStartButtonOnClick(StartActivityForResultTest.java:51)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
    at android.test.InstrumentationTestCase.access$000(InstrumentationTestCase.java:36)
    at android.test.InstrumentationTestCase$2.run(InstrumentationTestCase.java:189)
    at android.app.Instrumentation$SyncRunnable.run(Instrumentation.java:1602)
    at android.os.Handler.handleCallback(Handler.java:615)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4745)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    at dalvik.system.NativeStart.main(Native Method)

Test results for InstrumentationTestRunner=.F
Time: 3.248

FAILURES!!!
Tests run: 1,  Failures: 1,  Errors: 0


codeguru@trolloc:~/src/java/stackoverflow/sscce/StartActivityForResult/test$ adb logcat -d codeguru.startactivityforresult.StartActivityForResultTest:D codeguru.startactivityforresult.StartActivityForResult:D codeguru.startactivityforresult.ChildActivity:D *:S
D/codeguru.startactivityforresult.StartActivityForResultTest(  954): setUp()
D/codeguru.startactivityforresult.StartActivityForResult(  954): onCreate()
D/codeguru.startactivityforresult.StartActivityForResult(  954): Start button clicked
layne@trolloc:~/src/java/stackoverflow/sscce/StartActivityForResult/test$ 

据我所知道的,叫 startButton.performClick()不启动 ChildActivity 的实例。是什么给了?

As far as I can tell, calling startButton.performClick() doesn't start an instance of ChildActivity. What gives?

推荐答案

如图<一href="http://stackoverflow.com/questions/13041890/testing-that-an-activity-returns-the-expected-result/13113137#13113137">an回答我的相关问题之一,问题是,我的UI线程调用 waitForMonitorWithTimeout()。意识到这一点之后,它肯定使完整意义上的,因为 waitForMonitorWithTimeout()等待UI线程来完成一些动作(即显示一个活动的用户界面)。然而,在UI线程上调用它,我推迟了行动,从存在的。

As illustrated in an answer to one of my related questions, the problem is that I am calling waitForMonitorWithTimeout() on the UI Thread. After realizing this, it certainly makes complete sense because waitForMonitorWithTimeout() waits for the UI thread to complete some action (namely displaying an Activity's UI). However, by calling it on the UI thread, I am delaying that action from occuring.

这篇关于从@UiThreadTest调用waitForMonitorWithTimeout()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆