2012-02-15 97 views
9

试图编写我的第一个Android-by-TDD应用程序(我已经编写了一些没有TDD的小型Android应用程序,所以对环境非常熟悉),但是我似乎无法让我的脑海围绕如何编写我的第一个测试。单元测试Activity.startService()调用?

场景:

我有一个活动,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来执行这样的基本测试...

+0

您已经验证你的'Activity'的'的onCreate()'方法得到通过仪器叫什么?我没有看到你在那里做什么都有什么不妥。 –

+0

现在,这很有趣。事实并非如此。如果我明确地做了getInstrumentation()。callActivityOnCreate(...),它也不会被调用。但是如果我注释掉我的模拟上下文,就会调用它*为了传递呼叫,必须存在一些依赖于上下文的上下文。 – Jules

+0

是的。找到这个(http://www.paulbutcher.com/2011/03/mock-objects-on-android-with-borachio-part-2/),看看。本质上,'MockContext'几乎是无用的:)。 –

回答

6

只是为了总结与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()); 
} 
+1

由于ActivityTestCase和MockContext的弃用,是否有原始解决方案的替代方案?谢谢! –