11

我目前正在为一个 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)

有没有人已经IntentServiceServiceTestCase课堂上测试过?

谢谢!

4

5 回答 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函数

于 2013-10-23T21:06:18.430 回答
2

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

仍在尝试解决问题,但是对于您似乎没有收到对您的方法的调用的情况onHandleIntent(),(我对背后的技术不是很好,junit所以请原谅我使用术语)这应该是因为测试框架,根据您的代码,一旦您的调用startService返回,实际上会拆除或结束测试方法。onHandleIntent触发时间不够。

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

于 2011-08-12T13:48:40.797 回答
0

你只需要添加一个:

Thread.sleep(XXXXXXX); 

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

于 2013-07-04T15:07:51.120 回答
0

在 Android Studio 1.1 中,使用运行/调试配置运行测试时 | Android 在扩展 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> 

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

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

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

于 2015-02-20T03:11:55.300 回答
-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();
        }
    }
    
于 2014-11-19T18:08:09.533 回答