gpt4 book ai didi

android - 如何使用 Robolectric 测试 IntentService?

转载 作者:IT老高 更新时间:2023-10-28 23:11:21 24 4
gpt4 key购买 nike

我正在尝试使用 Robolectric 测试 IntentServiceonHandleIntent() 方法。

我开始使用以下服务:

Activity activity = new Activity();
Intent intent = new Intent(activity, MyService.class);
activity.startService(intent);

ShadowActivity shadowActivity = Robolectric.shadowOf(activity);
Intent startedIntent = shadowActivity.getNextStartedService();
assertNotNull(startedIntent);

似乎 startedIntent 不为空,但 onHandleIntent() 似乎没有被调用。

我应该如何测试它?

最佳答案

Robolectric 有一个 ServiceController它可以像 Activity 一样贯穿服务生命周期。该 Controller 提供了执行相应服务回调的所有方法(例如 controller.attach().create().startCommand(0, 0).destroy())。

理论上我们可以预期 IntentService.onStartCommand()将通过其内部 Handler 触发 IntentService.onHandleIntent(Intent)。然而,这个 Handler 使用了一个在后台线程上运行的 Looper,我不知道如何让这个线程进入下一个任务。一种解决方法是创建模拟相同行为的 TestService,但会在主线程(用于运行测试的线程)上触发 onHandleIntent(Intent)

@RunWith(RobolectricGradleTestRunner.class)
public class MyIntentServiceTest {
private TestService service;
private ServiceController<TestService> controller;

@Before
public void setUp() {
controller = Robolectric.buildService(TestService.class);
service = controller.attach().create().get();
}

@Test
public void testWithIntent() {
Intent intent = new Intent(RuntimeEnvironment.application, TestService.class);
// add extras to intent
controller.withIntent(intent).startCommand(0, 0);
// assert here
}

@After
public void tearDown() {
controller.destroy();
}

public static class TestService extends MyIntentService {
public boolean enabled = true;

@Override
public void onStart(Intent intent, int startId) {
// same logic as in internal ServiceHandler.handleMessage()
// but runs on same thread as Service
onHandleIntent(intent);
stopSelf(startId);
}
}
}

更新:或者,为 IntentService 创建一个类似的 Controller 非常简单,如下所示:

public class IntentServiceController<T extends IntentService> extends ServiceController<T> {
public static <T extends IntentService> IntentServiceController<T> buildIntentService(Class<T> serviceClass) {
try {
return new IntentServiceController<>(Robolectric.getShadowsAdapter(), serviceClass);
} catch (IllegalAccessException | InstantiationException e) {
throw new RuntimeException(e);
}
}

private IntentServiceController(ShadowsAdapter shadowsAdapter, Class<T> serviceClass) throws IllegalAccessException, InstantiationException {
super(shadowsAdapter, serviceClass);
}

@Override
public IntentServiceController<T> withIntent(Intent intent) {
super.withIntent(intent);
return this;
}

@Override
public IntentServiceController<T> attach() {
super.attach();
return this;
}

@Override
public IntentServiceController<T> bind() {
super.bind();
return this;
}

@Override
public IntentServiceController<T> create() {
super.create();
return this;
}

@Override
public IntentServiceController<T> destroy() {
super.destroy();
return this;
}

@Override
public IntentServiceController<T> rebind() {
super.rebind();
return this;
}

@Override
public IntentServiceController<T> startCommand(int flags, int startId) {
super.startCommand(flags, startId);
return this;
}

@Override
public IntentServiceController<T> unbind() {
super.unbind();
return this;
}

public IntentServiceController<T> handleIntent() {
invokeWhilePaused("onHandleIntent", getIntent());
return this;
}
}

关于android - 如何使用 Robolectric 测试 IntentService?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12025611/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com