Android:在工具测试中获取对已启动Service的引用 [英] Android: get reference to started Service in instrumentation test

查看:64
本文介绍了Android:在工具测试中获取对已启动Service的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正按照官方"测试您的服务"文档.

I'm trying to write instrumentation test for my NetworkMonitorService as described in the official "testing your service" documentation.

当前,我很困,因为我无法弄清楚如何获取对已启动服务的引用,以便向其中注入模拟并断言行为.

Currently I'm stuck because I can't figure out how can I grab a reference to the started service in order to inject mocks into it and assert behavior.

我的代码:

@RunWith(AndroidJUnit4.class)
@SmallTest
public class NetworkMonitorServiceTest {

    @Rule public final ServiceTestRule mServiceTestRule = new ServiceTestRule();

    @Test
    public void serviceStarted_someEventHappenedInOnStartCommand() {
        try {
            mServiceTestRule.startService(new Intent(
                    InstrumentationRegistry.getTargetContext(),
                    NetworkMonitorService.class));
        } catch (TimeoutException e) {
            throw new RuntimeException("timed out");
        }

        // I need a reference to the started service in order to assert that some event happened
        // in onStartCommand()...
    }
}

有问题的服务不支持绑定.我认为,如果我要实现对绑定的支持,然后在测试中使用它以获得对服务的引用,则它可以工作.但是,我不喜欢仅仅为了支持测试用例而编写生产代码...

The service in question doesn't support binding. I think that if I'd implement support for binding and then use this in test in order to get a reference to the service it could work. However, I don't like writing production code just for sake of supporting test cases...

那么,如何测试(仪器测试)不支持绑定的Service?

So, how can I test (instrumentation test) a Service that doesn't support binding?

推荐答案

用特殊版本用于测试"替换您的应用程序.通过提供自定义的仪器测试运行器来做到这一点.模拟您的依赖关系,这是测试应用程序". 查看详情

Replace your application with special version "for tests". Do it by providing custom instrumentation test runner. Mock your dependencies it this "app for tests". See for details

这是一个简化的示例,说明如何使用用于测试的应用".假设您要在测试期间模拟网络层(例如Api).

Here is a simplified example how "app for test" can be used. Let's assume you want to mock network layer (eg. Api) during tests.

public class App extends Application {
    public Api getApi() {
        return realApi;
    }
}

public class MySerice extends Service {
    private Api api;
    @Override public void onCreate() {
        super.onCreate();
        api = ((App) getApplication()).getApi();
    }
}

public class TestApp extends App {
    private Api mockApi;

    @Override public Api getApi() {
        return mockApi;
    }

    public void setMockApi(Api api) {
        mockApi = api;
    }
}

public class MyTest {
    @Rule public final ServiceTestRule mServiceTestRule = new ServiceTestRule();

    @Before public setUp() {
        myMockApi = ... // init mock Api
        ((TestApp)InstrumentationRegistry.getTargetContext()).setMockApi(myMockApi);
    }

    @Test public test() {
        //start service
        //use mockApi for assertions
    }
}

在示例中,依赖项注入是通过应用程序的方法getApi完成的.但是您可以以相同的方式使用Dagger或任何其他方法.

In the example dependency injection is done via application's method getApi. But you can use Dagger or any others approaches in the same way.

这篇关于Android:在工具测试中获取对已启动Service的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆