【问题标题】:Unit testing Activity.startService() call?单元测试 Activity.startService() 调用?
【发布时间】:2012-03-06 20:14:44
【问题描述】:

尝试编写我的第一个 Android-by-TDD 应用程序(我已经编写了一些没有 TDD 的小型 Android 应用程序,因此对环境很熟悉),但我似乎无法理解如何编写我的第一次测试。

场景:

我有一个活动 TasksActivity 和一个服务 TasksService。我需要测试 TasksActivity 在其 onStart() 方法中启动 TasksService。

我写的测试是这样的:

public class ServiceControlTest extends ActivityUnitTestCase<TasksActivity>{
public ServiceControlTest() {
    super(TasksActivity.class);
}

public void testStartServiceOnInit () {
    final AtomicBoolean serviceStarted = new AtomicBoolean(false);
    setActivityContext(new MockContext() {
        @Override
        public ComponentName startService(Intent service) {
            Log.v("mockcontext", "Start service: " + service.toUri(0));
            if (service.getComponent().getClassName().equals (TasksService.class.getName()))
                serviceStarted.set(true);
            return service.getComponent();
        }
    });
    startActivity(new Intent(), null, null);
    assertTrue ("Service should have been started", serviceStarted.get());
}           
}

在 TasksActivity 的 onCreate() 方法中,我有:

    startService(new Intent(this, TasksService.class));

我也试过

    getBaseContext().startService(new Intent(this, TasksService.class));

但在这两种情况下,我的 MockContext 的 startService 方法都不会被调用。有没有办法可以设置拦截这个方法?我真的不想为了执行这样的基本测试而开始包装基本的 Android API...

【问题讨论】:

  • 您是否确认您的ActivityonCreate() 方法正在通过检测被调用?我认为你在那里所做的事情没有任何问题。
  • 现在,这很有趣。它不是。如果我明确地执行 getInstrumentation().callActivityOnCreate(...),也不会调用它。但是如果我注释掉我的模拟上下文,它调用......必须对上下文做一些事情或其他的依赖才能通过调用。
  • 是的。找到这个(paulbutcher.com/2011/03/…),看看。从本质上讲,MockContext 几乎完全没用:)。
  • 是的,我刚找到同一篇文章,切换到ContextWrapper已经解决了问题。谢谢您的帮助。 :)

标签: android unit-testing junit tdd android-service


【解决方案1】:

总结一下在 cmets 中与 Brian Dupuis 的对话,问题在于 MockContext 没有提供测试仪器所需的设施,以便正确调用 onCreate()。从MockContext 切换到ContextWrapper 解决了这个问题。

因此,工作测试如下所示:

public void testStartServiceOnInit () {
    final AtomicBoolean serviceStarted = new AtomicBoolean(false);
    setActivityContext(new ContextWrapper(getInstrumentation().getTargetContext()) {
        @Override
        public ComponentName startService(Intent service) {
            Log.v("mockcontext", "Start service: " + service.toUri(0));
            if (service.getComponent().getClassName().equals ("net.meridiandigital.tasks.TasksService"))
                serviceStarted.set(true);
            return service.getComponent();
        }
    });
    startActivity(new Intent(), null, null);
    assertTrue ("Service should have been started", serviceStarted.get());
}

【讨论】:

  • 随着 ActivityTestCase 和 MockContext 的弃用,是否有替代原始解决方案的方法?谢谢!
猜你喜欢
  • 2018-08-06
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-25
相关资源
最近更新 更多