如何验证IntentService是否启动



我正在尝试用Espresso-2.2测试我的应用程序行为

在主活动上,当按钮被按下时,服务和另一个活动正在启动:

public class MainActivity extends Activity {
    public void onButtonClicked() {
        startActivity(SecondActivity.getStartIntent());
        startService(MyIntentService.getStartIntent());
    }
}

我正在测试预期的组件是否正在启动:

public class MainActivityTest {
    @Rule
    public final IntentsTestRule<MainActivity> intentsRule = new IntentsTestRule<>(MainActivity.class, true);
    @Test
    public void shouldStartServiceOnButtonClicked() {
        onView(withId(R.id.button)).perform(click());
        intended(hasComponent(hasClassName(SecondActivity.class.getName())));
        intended(hasComponent(hasClassName(MyIntentService.class.getName())));
    }
}

但是我得到错误:

Caused by: junit.framework.AssertionFailedError: Wanted to match 1 intents. Actually matched 0 intents.
IntentMatcher: has component: has component with: class name: is "com.example.MyIntentService" package name: an instance of java.lang.String short class name: an instance of java.lang.String
Matched intents:[]
Recorded intents:
-Intent { cmp=com.example/.SecondActivity (has extras) } handling packages:[[com.example]], extras:[Bundle[...]])
at junit.framework.Assert.fail(Assert.java:50)

注册了Start of SecondActivity。为什么我的IntentService没有注册(我检查了它是否已启动)?

在当前espresso-intents提供的功能下,这似乎是不可能的

我在源代码中挖掘,因为我试图做类似的事情,这是我发现的:

'intended'匹配器通过查看记录的intent列表来工作。当调用Intents.init()时,这些由一个回调函数跟踪,该回调函数在IntentMonitor实例中注册。IntentMonitor实例由当前Instrumentation定义。当IntentMonitor的signalIntent()被调用时,Intents中的回调函数将被触发。

问题在于,当你用intent调用activity.startService()时,signalIntent()实际上从来没有被调用过。这是因为AndroidJunitRunner案例中的signalIntent()只会被暴露在ExposedInstrumentationApi上的方法调用(恰好只与各种startActivity()方法相关)。为了在startService()中使用espresso- intenents,似乎需要为startService()提供一个插装钩子,以便在IntentMonitor上调用signalIntent()。

我没有将自定义Instrumentation添加到我的测试apks的经验,但这将是我的下一个调查途径。如果我发现任何有效的方法,我会更新我的答案

我可以做出一个有根据的猜测,问题是您试图断言在调用startService()之后立即创建并运行IntentService,而实际上startService()不是同步调用。它确实发生在UI线程上,但不是立即发生。您可以将验证推迟几个周期,然后检查服务是否启动。

最新更新