Android ServiceTestCase适用于IntentService

11

我目前正在为一个安卓应用编写单元测试并遇到了以下问题:

我使用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)的调用。

有人已经使用ServiceTestCase类测试过IntentService吗?

谢谢!


我还在测试一个IntentService,显然它没有被Android测试框架正确设置。我看不到其他原因导致我的测试失败。http://stackoverflow.com/questions/6975348/strange-nullpointer-exception-in-android-test-case - siamii
5个回答

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函数。

2

我刚开始测试自己的IntentService,但是这证明有点棘手。

还在试图弄清楚事情,但是如果似乎您没有收到对您的方法onHandleIntent()的调用(我不太擅长junit背后的技术术语,所以请原谅我的用词),那应该是因为基于您的代码的测试框架实际上在您调用startService后就拆除或结束了测试方法。 onHandleIntent没有足够的时间来被触发。

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


1
你是对的,实际上如果单元测试被拆除,该服务不会正确启动。我通过在测试中添加 Thread.sleep 并定期检查服务结果来修复它。 - Dominik Helleberg
我目前正在使用信号量的路径上,但是当使用ResultReceiver的IntentService时,知道何时释放信号量以便拆除测试变得非常笨拙。也许我应该考虑使用Thread.sleep。 - yjw

0

你只需要添加一个:

Thread.sleep(XXXXXXX); 

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


0
在Android Studio 1.1中,当使用Run/Debug Configuration | 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> 

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

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

像其他人一样,我将我的代码放在onHandleintent()中,根据上述文档的指示,然而,ServiceTestCase仅测试onStart和onStartCommand如上所示。


-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()); //你的断言服务特定断言 }
在服务的onStart中,我们检查传递的特定Extra并调用要测试的方法。 当处理意图时,不会执行此操作。
@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(); } }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接