我的活动包含以下代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (mUser.getLoggedInUser() != null) {
startActivity(new Intent(this, MainActivity.class));
finish();
return;
}
}
因此,如果用户已登录,则应启动MainActivity
并立即完成。我想编写一个单元测试来验证MainActivity是否实际启动。我使用Espresso和IntentsTestRule
@Test
public void testUserLoggedIn() {
Intents.init();
mUser = new User();
mActivityRule.launchActivity(null);
intended(hasComponent(MainActivity.class.getName()), times(1));
Intents.release();
}
mUser
通过依赖注入设置,活动按预期运行。但是,测试失败,输出如下:
java.lang.RuntimeException: Could not launch intent Intent { act=android.intent.action.MAIN flg=0x14000000 cmp=global.snappy.android/.activities.onboarding.FirstStartActivity } within 45 seconds. Perhaps the main thread has not gone idle within a reasonable amount of time? There could be an animation or something constantly repainting the screen. Or the activity is doing network calls on creation? See the threaddump logs. For your reference the last time the event queue was idle before your activity launch request was 1486519735157 and now the last time the queue went idle was: 1486519735163. If these numbers are the same your activity might be hogging the event queue.
at android.support.test.runner.MonitoringInstrumentation.startActivitySync(MonitoringInstrumentation.java:360)
at android.support.test.rule.ActivityTestRule.launchActivity(ActivityTestRule.java:219)
at global.snappy.android.activities.onboarding.FirstStartActivityTest.testUserLoggedIn(FirstStartActivityTest.java:108)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at android.support.test.internal.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:270)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1886)
在Espresso有时间附加测试之前,活动似乎已关闭。删除finish()
中的onCreate()
来电不会改变此问题。有没有办法测试这种行为?浓咖啡会更好,但如果需要,我也可以使用其他框架。
答案 0 :(得分:1)
您可以为自己的活动创建Spy
课程。
然后,您可以使用startActivity
作为参数来检查是否调用了MainActivity
。
测试框架很好,但有时简单的代码看起来更好,而且更灵活。
您的Spy类看起来像这样(假设您的活动名称为MyActivity
)。
public class MyActivitySpy extends MyActivity {
private boolean startActivityWasCalledToStartMainActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public startActivity(Intent intent) {
if(intentWithActivityName(intent, MainActivity.class.getSimpleName())) {
startActivityWasCalledToStartMainActivity ;
}
}
private boolean intentWithActivityName(Intent intent, String activityName) {
activityName.equals(intent.getComponent().getClassName());
}
public boolean wasStartActivityCalledToStartMainActivity() {
return startActivityWasCalledToStartMainActivity;
}
}
然后,你的测试就像。
@Test
public void testUserLoggedIn() {
//launch MyActivitySpy instead of your real MyActivity
assertTrue(myActivitySpy.wasStartActivityCalledToStartMainActivity());
}
答案 1 :(得分:-1)
好的,我找到了解决方案。基本上,使用IntentsTestRule
代替intending()
,并使用intended()
拦截所有意图。然后,您可以使用@Rule
public ActivityTestRule<FirstStartActivity> mActivityRule =
new ActivityTestRule<>(FirstStartActivity.class, true, false);
@Test
public void testStartMainActivity() {
Intents.init();
intending(anyOf(hasComponent(MainActivity.class.getName()), hasComponent(OnboardingActivity.class.getName())))
.respondWith(new Instrumentation.ActivityResult(Activity.RESULT_CANCELED, null));
// inject User instance here
mActivityRule.launchActivity(null);
intended(hasComponent(MainActivity.class.getName()), times(1));
Intents.release();
}
验证意图。
var Myform=$('#saveForm');
$(document).on('click','.btn-finish',function(e){
$('#saveForm')[0].submit();
});