没有具体的广播接收器的集成测试 Activity.class

Integration Test with a Broadcast Receiver without a concrete Activity.class

我的应用程序通过 IntentFilters 提供了一个接口供其他应用程序与之通信。

我在内部使用 BroadcastReceivers 将那些过滤后的 Intents 翻译成 POJO,然后 post 将它们翻译成我的 EventBus (Greenrobot v3)。

我的问题:
我将 ActivityTestRule 与存根 MainActivity.class 结合使用 - 文件以获得 Context,我可以在其上注册我的 BroadcastReceiver 并发送 Intents:

mContext = mActivityRule.getContext();

我真的很想使用某种 "anonymous activity"。这样我就可以摆脱我的 Stub MainActivity.class 文件。我尝试使用:

mContext = InstrumentationRegistry.getContext();

但是一旦我注册我的接收器,测试就会抛出 java.lang.SecurityException。有没有办法绕过这个异常?

这是我的测试用例的骨架:

@MediumTest
@RunWith(AndroidJUnit4.class)
public class WhosebugQuestionTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule 
        = new ActivityTestRule<>(MainActivity.class);

    Person mPerson;
    CountDownLatch mLock;
    mContext = mActivityRule.getActivity();

    @Before
    public void setUp() {
        mLock = new CountDownLatch(1);
        mPerson = null;

        PersonReceiver receiver = new PersonReceiver();
        IntentFilter filter = receiver.getPredefinedFilter();
        mContext.registerReceiver(receiver, filter);
    }

    @Test
    public void PersonReceiver_seats_a_Person_on_the_EventBus() throws InterruptedException {
        EventBus.getDefault().register(this);

        mContext.sendBroadcast(new MockedPersonIntent("Waldo"));

        mLock.await();

        assertThat(Person.getName(), is(equalTo("Waldo")));
    }

    @Subscribe
    public void onPerson(Person person) {
        Person = person;
        mLock.countDown();
    }
}

解决方案比我预期的要简单。

mContext = InstrumentationRegistry.getTargetContext();

发生安全异常是因为我使用了 getContext(),其中 returns 是相对于包的上下文,而 getTargetContext() returns 是相对于整个应用程序的上下文,它也我的接收器注册到。

完全如 Documentation

中所述