pro*_*typ 5 java android unit-testing android-service robolectric
在使用测试覆盖我的完整 Android 项目时,我试图找到一种方法来使用 Robolectric 测试我的服务。我需要测试的服务包含很多需要测试的逻辑。
经过一番研究,我从 robolectric找到了一个如何使用 shadowService 测试服务的代码示例,但我仍然不知道如何启动该服务并测试其功能。
首先,我想创建所有依赖项的模拟并将它们注入到服务中。然后对于每种方法,我想编写测试以及具有不同模拟依赖方法的服务。
我怎样才能做到这一点?测试 Android 服务时的最佳实践是什么?有人知道一些好的方法吗?
我的测试和服务到目前为止,但服务没有启动(调试器不会进入服务内的断点):
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class , sdk = 23)
public class MyServiceTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock
Context context;
@Mock
ApiService apiService;
@Mock
ServiceManagerImpl serviceManager;
@InjectMocks
private MyService myService;
private ShadowService shadowService;
@Before
public void setUp(){
// explicit service creation from robolectric example
this.updateService = Robolectric.setupService(UpdateService.class);
this.shadowService = shadowOf(this.updateService);
MockitoAnnotations.initMocks(this);
when(this.apiService.fetchData()).thenReturn(42);
}
@Test
public void testService(){
this.updateService.startService(new Intent());
// Test of a service function here ...
}
}
Run Code Online (Sandbox Code Playgroud)
我的服务示例:
public class UpdateService extends Service {
@Inject
Context context;
@Inject
ApiService apiService;
@Inject
ServiceManager serviceManager;
private List<ApkRelease> fetchedData;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
((MyApplication) getApplication()).getComponent().inject(this);
this.fetchData();
return super.onStartCommand(intent, flags, startId);
}
private void fetchData() {
Call<List<Data>> call = this.apiService.getData();
call.enqueue(new Callback<List<Data>>() {
@Override
public void onResponse(Call<List<Data>> call, Response<List<Data>> response) {
if (response.body() != null) {
if (!response.body().isEmpty()) {
fetcheData = response.body();
processNextData();
} else {
stopSelf();
}
}
}
@Override
public void onFailure(Call<List<Data>> call, Throwable t) {
ACRA.getErrorReporter().handleException(t);
startUpgrade();
}
});
}
private void processNextData() {
if (this.fetchedData.isEmpty()) {
startOtherStuff();
return;
}
this.processData(this.fetchedReleases.remove(0));
}
private void processData(Data data, ResponseBody responseBody) {
//process Data
....
this.processNextData();
}
private void startOtherStuff() {
Intent intent = new Intent(this.context, UpgradeService.class);
this.context.startService(intent);
this.stopSelf();
}
...
}
Run Code Online (Sandbox Code Playgroud)