2012-02-15 144 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的棄用,是否有原始解決方案的替代方案?謝謝! –