IntentService的Android ServiceTestCase

时间:2011-07-12 15:46:23

标签: android servicetestcase

我目前正在为Android应用程序编写单元测试,并且偶然发现了以下问题:

我使用ServiceTestCase来测试IntentService,如下所示:

@Override
public void setUp() throws Exception {
    super.setUp();      
}

public void testService()
{
    Intent intent = new Intent(getSystemContext(), MyIntentService.class);
    super.startService(intent);     
    assertNotNull(getService());        
}

但是我注意到我的IntentService已创建(表示已调用onCreate),但我从未接到onHandleIntent(Intent intent)

的来电

是否有人已经使用IntentService课程测试了ServiceTestCase

谢谢!

5 个答案:

答案 0 :(得分:6)

这有点晚了,但我只是在努力解决这个问题。您可以通过创建一个简单地覆盖服务的onStart的类来解决这个问题,这样它就可以直接调用onHandleIntent。例如,如果你有一个LocationUpdaterService,你可以创建一个假的类来覆盖onStart函数,如下所示:

public class LocationUpdaterServiceFake extends LocationUpdaterService {

@Override
public void onStart(Intent intent, int startId) {
    onHandleIntent(intent);
    stopSelf(startId);
}

LocationUpdaterService是IntentService的子类,因此在编写测试时,只需使用LocationUpdaterServiceFake这样的类

public class LocationUpdateServiceTest extends ServiceTestCase<LocationUpdaterServiceFake> {

public LocationUpdateServiceTest()
{
    super(LocationUpdaterServiceFake.class);
}

public void testNewAreaNullLocation()
{
    Intent intent = new Intent();
    intent.setAction(LocationUpdaterService.ACTION_NEW_AREA);

    startService(intent);
}

}

现在每当您致电startService时,它都会绕过IntentService中的线程代码,只需调用您的onHandleIntent函数

答案 1 :(得分:2)

我刚刚开始测试我自己的IntentService,这证明有点头疼。

仍在努力解决问题,但对于您似乎没有接到对方法onHandleIntent()的调用的情况,(我对junit背后的技术性能不是很了解,所以请原谅我使用的术语)应该是因为基于你的代码的测试框架在你startService的调用返回后实际上撕下或结束了测试方法。 <{1}}没有足够的时间被触发。

我通过在我的测试用例中添加一个无限循环验证了上述理论 - 只有这样我才能在onHandleIntent中看到我的日志语句。

答案 2 :(得分:0)

你只需添加一个:

Thread.sleep(XXXXXXX); 

在startService之后选择XXXX,然后它会让线程进入onHandleIntent方法。

答案 3 :(得分:0)

在Android Studio 1.1中,使用“运行/调试配置”运行测试时Android Tests工具在任何扩展IntentService的测试代码(UUT)下,ServiceTestCase.java(JUnit?)代码不会调用UUT中的onHandleIntent(Intent intent)方法。 ServiceTestCase仅调用onCreate,因此问题出在测试代码中。

protected void startService(Intent intent) {
    if (!mServiceAttached) {
        setupService();
    }
    assertNotNull(mService);

    if (!mServiceCreated) {
        mService.onCreate();
        mServiceCreated = true;
    }
    mService.onStartCommand(intent, 0, mServiceId);

    mServiceStarted = true;
}

在我的文件smSimulatorTest.java中:

public class smSimulatorTest extends ServiceTestCase<smSimulator> 

此时,我正在测试框架中寻找通过Intents测试UUT的其他解决方案,因为这是IntentService实例化的方式。

http://developer.android.com/reference/android/app/IntentService.html - 要使用它,请扩展IntentService并实现onHandleIntent(Intent)。 IntentService将接收Intents,启动工作线程,并根据需要停止服务。

我和其他人一样,按照上述文档的指示将我的代码放在onHandleintent()中,但是,ServiceTestCase仅测试onStart和onStartCommand。

答案 4 :(得分:-1)

这是我现在的方法:

  1. 调用服务的启动Intent指定要测试的Service方法

    
    public void test_can_do_the_work() {
        Intent startIntent = new Intent();
        startIntent.putExtra("IN_TEST_MODE", "TEST_SPECIFIC_METHOD");
        startIntent.setClass(getContext(), MyServiceToTest.class);
        startService(startIntent);
        assertNotNull(getService()); // Your assertion Service specific assertion
    }
    
  2. 在服务onStart中,我们检查特定的Extra传递并调用方法进行测试。当处理Handle意图时,这将不会执行。

    
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        String in_test_mode = intent.getStringExtra("TEST_SPECIFIC_METHOD");
        if(in_test_mode != null){
            doServiceWork();
        }
    }