2012-07-16 35 views
0

我有简单的ServiceTestCase和一个只包含生命周期方法的空IntentSerice,Service也是注册的AndroidManifest.xml,还有一个Action标签“com.tut.my.service.DATAUPDATE”。为什么testServiceTestCaseSetupProperly(...)在自定义测试之后被调用?

服务的调用工作得很好,所有的循环方法都按顺序显示,但是在我的自定义测试结束后发生了一些奇怪的事情。 ServiceTestCase在我的自定义测试后发出方法testServiceTestCaseSetUpProperly()以确保setupService()正确运行。

因此,我正在寻找并找到一些关于setupService()的interesting blog,但结论并不令人满意。博客作者建议 - 出于某种原因 - 不要在setUp()中致电startService(...),因为他清楚地明白了为什么它不是一个好主意。

但是,自定义测试后调用testServiceTestCaseSetUpProperly()时出现的问题是调用MyService服务的新实例。这最终调用onCreate和 服务由于某种原因死亡,finito ...但所有测试都通过成功。

下面是该服务的来源:

public class MyService extends IntentService { 

    public static final String INTENT = "com.tut.my.service.DATAUPDATE"; 

    public MyService() { 
    super(INTENT); 
    Log.d(getClass().getSimpleName(), "called: std c-tor()"); 
    } 

    @Override 
    public void onCreate() { 
    super.onCreate(); 
    Log.d(getClass().getSimpleName(), "called: onCreate()"); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
    Log.d(getClass().getSimpleName(), "called onStartCommand() --> intent: " + intent.getAction() + " flags: " + flags + " startID: " + startId); 
    return super.onStartCommand(intent, flags, startId); 
    } 

    @Override 
    public void onDestroy() { 
    super.onDestroy(); 
    Log.d(getClass().getSimpleName(),"called: onDestory()"); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
    Log.d(getClass().getSimpleName(), "called: onHandleIntent() --> Intent: " + intent.getAction()); 
    setPriceData(); 
    } 
} 

这里是ServiceTestCase

@MediumTest 
public class MyServiceTest extends ServiceTestCase<MyService> { 

    Context mCtx = null; 

    public MyServiceTest() { 
    super(MyService.class); 
    } 

    @Override 
    protected void setUp() throws Exception { 
    super.setUp(); 
    mCtx = getSystemContext(); 
    } 

    @MediumTest 
    public void testGetMyServiceData() throws InterruptedException { 
    Intent i = new Intent(MyService.INTENT); 
    Log.d(getClass().getSimpleName(), "startService(i)"); 
    mCtx.startService(i); 

    // throttle the instrumentation thread so the service 
    // can be instantiated for sure 
    Log.d(getClass().getSimpleName(), "before Thread Sleep"); 
    Thread.sleep(8000); // needs 10 seconds before ANR 
    Log.d(getClass().getSimpleName(), "after Thread Sleep"); 
    } 
} 

和相应的(剥离)的logcat输出:

I/TestRunner(11954): started: testGetMyServiceData(com.tut.my.service.MyServiceTest) 
D/MyServiceTest(11954): startService(i)  
D/MyService(11954): called: std c-tor() 
D/MyServiceTest(11954): before Thread Sleep 
D/MyService(11954): called: onCreate() 
D/MyService(11954): called onStartCommand() --> intent: com.tut.my.service.DATAUPDATE flags: 0 startID: 1 
D/MyService(11954): called: onHandleIntent() --> Intent: com.tut.my.service.DATAUPDATE 
D/MyService(11954): called: onDestory() 
D/MyServiceTest(11954): after Thread Sleep 
I/TestRunner(11954): finished: testGetMyServiceData(com.tut.my.service.MyServiceTest) 
I/TestRunner(11954): passed: testGetHarvestData(com.tut.my.service.MyServiceTest) 
I/TestRunner(11954): started: testServiceTestCaseSetUpProperly(com.tut.my.service.MyServiceTest) 
D/MyService(11954): called: std c-tor() 
I/TestRunner(11954): finished: testServiceTestCaseSetUpProperly(com.tut.my.service.MyServiceTest) 
I/TestRunner(11954): passed: testServiceTestCaseSetUpProperly(com.tut.my.service.MyServiceTest) 
I/TestRunner(11954): started: testAndroidTestCaseSetupProperly(com.tut.my.service.MyServiceTest) 
I/TestRunner(11954): finished: testAndroidTestCaseSetupProperly(com.tut.my.service.MyServiceTest) 
I/TestRunner(11954): passed: testAndroidTestCaseSetupProperly(com.tut.my.service.MyServiceTest) 
I/ActivityManager(71): Force stopping package com.tut.my.service uid=10036 
I/Process(71): Sending signal. PID: 11954 SIG: 9 

所以问题是,为什么testServiceTestCaseSetupProperly()在最后被调用,而不是第一个?以及为什么MyService对象如此不正常地死去。

编辑:为了更精确:

我关心的重要组成部分,是的onCreate粗鲁的电话。

I/TestRunner(11954): started: testServiceTestCaseSetUpProperly(com.tut.my.service.MyServiceTest) 
D/MyService(11954): called: std c-tor() <--- ONLY one call to onCreate 
I/TestRunner(11954): finished:testServiceTestCaseSetUpProperly(com.tut.my.service.MyServiceTest) 
  • 如果我去分配中的onCreate资源,谁主张我去收拾分配resrouces?
  • 为什么在所有测试结束时检查正确的服务设置?
  • 为什么它会被杀呢?
+0

尝试使用'startService(new Intent(getContext(),MyService.class));'启动您的服务并查看它是否修复了服务死锁问题。 – yorkw 2012-07-16 05:15:41

+0

@ yorkw已经尝试过,没有效果。 – LikeYou 2012-07-16 05:22:50

+0

@yorkw顺便说一句,我想在所有测试的第一位看到testServiceTestCaseSetupProperly(),如果它发生的话。 – LikeYou 2012-07-16 05:24:37

回答

2

JUnit 3使用反射来获取要运行的测试。不保证测试是以任何特定顺序运行的。 此外,单元测试应该是彼此独立的,所以它们的执行顺序应该不相关。

+0

对我来说这很好,只要我的物品不会被斧子杀死。无论如何,如果它在测试序列的开始时不会发生,那么还需要进行“SetupProperly”测试,同样,setUp()在其他地方调用,但启动无意义。 – LikeYou 2012-07-16 06:34:22

+0

有保证的是setUp()在每次测试之前被调用,tearDown()之后被调用。 – 2012-07-16 19:07:11

+0

阅读[setUp()]的开发者文档(http://developer.android.com/reference/android/test/AndroidTestCase.html#setUp%28%29)它说:“设置夹具,例如,打开一个网络连接,这个方法在<<执行测试之前被称为>>。对于[tearDown()](http://developer.android.com/reference/android/test/AndroidTestCase.html#tearDown%28%29)它说:“放下灯具,例如关闭网络连接这个方法在<<执行测试之后被称为>>。所以它很可能会在开始时调用setUp(),最后调用tearDown()。 – LikeYou 2012-07-16 21:00:22

相关问题