如何检查发送的预期意图而不是在Espresso中实际启动活动?

时间:2016-09-14 09:07:26

标签: android android-intent android-activity android-espresso android-instrumentation

我有一个UI测试点击按钮,然后在其onClickListener中启动一个新的Activity。该测试检查是否发送了预期意图。

我的问题是,我想测试预期意图是否发送而不实际启动活动。因为我发现新活动初始化了它的状态,并且后续测试变得不稳定。

我知道有两个Espresso Intents api,intendedintending,但都无法满足我的需求。 intended api实际上启动了目标活动,intending api没有启动该活动,但它调用onActivityResult回调,我也不想要。因为我担心onActivityResult内的代码可能会导致另一种瑕疵。另外intending没有断言是否发送了匹配意图,它只是在找到匹配意图时调用onActivityResult回调,这意味着我必须检查是否调用了onActivityResult

有没有什么干净的方法可以达到我的目的?

3 个答案:

答案 0 :(得分:10)

如果您想测试是否在没有实际启动活动的情况下发送预期意图,您可以通过使用activityResult捕获意图然后捕获活动来执行此操作:

Intent intent = new Intent();
ActivityResult intentResult = new ActivityResult(Activity.RESULT_OK,intent);

intending(anyIntent()).respondWith(intentResult);

onView(withId(R.id.view_id_to_perform_clicking)).check(matches(isDisplayed())).perform(click());

intended(allOf(hasComponent(ActivityToBeOpened.class.getName())));

这将捕获任何启动ActivityToBeOpened的尝试。如果您想要更具体,您还可以使用Extras捕获意图:

intended(allOf(hasComponent(ActivityToBeOpened.class.getName()), hasExtra("paramName", "value")));

希望有所帮助。

答案 1 :(得分:2)

Espresso的Intents课程是一个简洁而方便的课程,但如果它不能满足您的需求,那么还有另一种选择。如果您使用AndroidJUnit4测试运行器,则可以使用Instrumentaion获取InstrumentationRegistry.getInstrumentation()实例,然后您可以添加Instrumentation.ActivityMonitor实例。

Instrumentation.ActivityMonitor am = new Instrumentation.ActivityMonitor("YOUR_ACTIVITY", null, true);
InstrumentationRegistry.getInstrumentation().addMonitor(am);
onView(withId(R.id.view_id_to_perform_clicking)).check(matches(isDisplayed())).perform(click());
assertTrue(InstrumentationRegistry.getInstrumentation().checkMonitorHit(am, 1));

ActivityMonitor构造函数的第三个参数告诉我们要阻止活动启动。请注意,这种方法有其局限性。与Espresso Intents'相比。 rich Matcher support,您无法为ActivityMonitor设置多个条件。

您可以在ApiDemos中找到多个样本,尤其是在ContactsSelectInstrumentation课程中。

答案 2 :(得分:1)

实际上,您可以阻止任何启动外部或您自己活动的意图,但仍然使用丰富的Espresso Intents API:

    Instrumentation.ActivityMonitor soloMonitor = solo.getActivityMonitor();
    instrumentation.removeMonitor(soloMonitor);
    IntentFilter filter = null;
    // Block any intent
    Instrumentation.ActivityMonitor monitor = instrumentation.addMonitor(filter, null, true);
    instrumentation.addMonitor(soloMonitor);

    // User action that results in an external browser activity being launched.
    user.clickOnView(system.getView(R.id.callButton));
    instrumentation.waitForIdleSync();

    Intents.intended(Matchers.allOf(
            IntentMatchers.hasAction(Matchers.equalTo(Intent.ACTION_VIEW)),
            IntentMatchers.hasData(Matchers.equalTo(Uri.parse(url))),
            IntentMatchers.toPackage(chromePackage)));

    instrumentation.removeMonitor(monitor);

你能够做到这一点,因为即使你阻止它们,Espresso Intents仍会记录每个Intent和IntentMonitor回调。查看Espresso Intents的源代码,了解他们如何做到这一点。

如果您使用Robotium Solo框架,则需要在自己的ActivityMonitor之前移动它们。否则只需跳过与此相关的行。