从@UiThreadTest调用waitForMonitorWithTimeout() [英] Call waitForMonitorWithTimeout() from a @UiThreadTest
问题描述
要说明我的最新问题,编写JUnit测试我的Android应用程序,我写了一个简单的例子,有两个活动, 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屋!