Android的服务不是由JUnit测试启动(Android service not launche

2019-06-26 02:07发布

我有这个测试类测试远程服务:

public class CoreServiceBasicTest extends ServiceTestCase<CoreService> implements ServiceConnection {

    /** Tag for logging */
    private final static String TAG = CoreServiceBasicTest.class.getName();

    /** Receive incoming messages */
    private final Messenger inMessenger = new Messenger(new IncomingHandler());

    /** Communicate with the service */
    private Messenger outMessenger = null;

    /** Handler of incoming messages from service */
    private static class IncomingHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            Log.d(TAG, "Incoming message");
        }
    }

    /** Constructor for service test */
    public CoreServiceBasicTest() {
        super(CoreService.class);
    }

    /** Start the service */
    @Override
    public void setUp() {

        // Mandatory
        try {
            super.setUp();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Start the service
        Intent service = new Intent();
        service.setClass(this.getContext(), CoreService.class);
        startService(service);
        Log.d(TAG, "Service started");
    }

    public void onServiceConnected(ComponentName className, IBinder service) {
        outMessenger = new Messenger(service);
        Log.d(TAG, "Service attached");
    }

    public void onServiceDisconnected(ComponentName className) {
        // TODO Auto-generated method stub

    }

    @SmallTest
    public void testBindService() {
        // Bind to the service
        Intent service = new Intent();
        service.setClass(getContext(), CoreService.class);
        boolean isBound = getContext().bindService(service, this, Context.BIND_AUTO_CREATE);
        assertTrue(isBound);
    }
}

问题是,startService(服务)在SETUP()方法不正确启动该服务。 这就是AVD显示:

正如你所看到的,进程启动,但服务没有。 然后在testBindService() assertTrue(isBound)失败。

如果我从活动推出的服务不会出现这种情况:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Start the Core service
    Intent service = new Intent();
    service.setClass(this, CoreService.class);

    if (startService(service) == null) {
        Toast.makeText(this, "Error starting service!", Toast.LENGTH_LONG).show();
        Log.e(TAG, "Error starting service");
    } else {
        Toast.makeText(this, "Service started sucessfully", Toast.LENGTH_LONG).show();
    }

    // Die
    finish();
}

这里的服务正确启动,如下图所示。

我怎样才能启动并绑定到使用斜挎带从Android测试项目活动通信的远程服务?

Answer 1:

的Android测试项目(test.apk)的整点是到仪器中的应用项目(app.apk)和单元测试它们与应用程序项目相关联的Android组件(活动,服务和等),在另一字,单元 - 测试活性和服务所创建和操纵内部app.apk。

你不应该写你MessengerService实现部分(信使,IncomingHandler和等)下测试项目ServiceTestCase里面执行第二次。 MessengerService实现只需要在你的应用程序项目的CoreService.java文件写入一次。

ServiceConnection用于活动和服务之间的相互通信,如我们在这里使用ServiceTestCase(意味着单元测试服务,与其他组件通信外的范围因此不被认为是),我们不需要ServiceConnection实现。 唯一ServiceConnection确实是初始化一个坚实的使者对象,这样我们就可以在以后使用,一旦服务被正确创建:

public void onServiceConnected(ComponentName className, IBinder service) {
  // This is what we want, we will call this manually in our TestCase, after calling
  // ServiceTestCase.bindService() and return the IBinder, check out code sample below.
  mService = new Messenger(service);
}

还要注意的是,你不需要调用ServiceTestCase.startService()在这种情况下,ServiceTestCase.bindService()将正常启动服务(如果它尚未启动),并返回一个对象的IBinder我们需要使用初始化使者后面的对象。

说,如果在CoreService.java您IncomingHandler.handleMessage()impelementation是这样的:

... ...

switch (msg.what) {
  case MSG_SAY_HELLO:
    msgReceived = true;
    break;

... ...

为了测试ServiceTestCase发送消息的功能:

... ...

IBinder messengerBinder = null;

@Override
public void setUp() throws Exception {
  super.setUp();
  // Bind the service and get a IBinder:
  messengerBinder = bindService(new Intent(this.getContext(), CoreService.class));
  //log service starting
  Log.d(TAG, "Service started and bound");
}

public void testSendMessage() {
  // Use IBinder create your Messenger, exactly what we did in ServiceConnection callback method:
  Messenger messenger = new Messenger(messengerBinder);
  Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
  messenger.send(msg);
  // Do some assert stuff here
  ... ...
}

... ...

如果你想测试活动和服务之间的通信,然后ServiceTestCase不适合在这种情况下。 考虑使用ActivityInstrumentationTestCase2实际测试活动(其绑定到您的CoreService,从而使您能够间接地测试你的服务功能的能力。



Answer 2:

刚看的ServiceTestCase文档它说,测试框架延迟启动该服务 ,直到你的一种测试方法调用ServiceTestCase.startService()ServiceTestCase.bindService()

看着你的代码中调用ServiceTestCase.startService()在你的setUp()方法,而不是在一个测试方法 。 这不启动该服务还没有。 它正在等待你的一种测试方法来调用ServiceTestCase.startService()ServiceTestCase.bindService()

您的测试方法testBindService()并没有叫ServiceTestCase.bindService()而是它调用Context.bindService()和失败。 测试框架仍然在等待,所以这就是为什么该服务未启动。

再来看看在链接的开发人员文档生命周期支持的讨论。



文章来源: Android service not launched by JUnit test