不是JUnit测试推出Android服务 [英] Android service not launched by JUnit test

查看:137
本文介绍了不是JUnit测试推出Android服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have this test class to test a remote service:

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(服务),在设置()方法不正确地启动该服务。这就是AVD显示:

The problem is that startService(service) in the setUp() method does not launch the service correctly. This is what the AVD shows:

正如你所看到的,这个过程被启动,但服务不。然后在 testBindService() assertTrue(一个isBound)失败。

As you can see, the process is launched but the service is not. Then on testBindService(), assertTrue(isBound) fails.

如果我启动该服务的活动,这不会发生:

This doesn't happen if I launch the service from an Activity:

@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();
}

下面的服务被正确启动,如下所示。

Here the service is started correctly, as shown below.

我如何开始,并绑定到使用信使从一个Android测试项目?

How can I start and bind to a remote service that uses Messenger to communicate with activities from an Android Test Project?

推荐答案

Android的测试项目(test.apk)的全部意义在于仪器的应用程序项目(app.apk)和单元测试的Andr​​oid组件(活动,服务等),它们与应用项目相关的,换句话说,是创建和操纵内部app.apk。该单元测试活动和服务

The whole point of Android Test Project (test.apk) is to instrument the Application Project (app.apk) and unit-test the Android components (Activity, Service and etc) which are associated with Application Project, in another word, unit-testing Activity and Service that is created and manipulated inside app.apk.

您应该没有写你的MessengerService实现部分(信使,IncomingHandler等)ServiceTestCase实现内部第二次下测试项目。 MessengerService实现只需要在你的应用程序项目的CoreService.java文件写一次。

You should not write your MessengerService implementation partially (Messenger, IncomingHandler and etc) second time inside ServiceTestCase implementation under Test project. MessengerService implementation only need to be written once in your Application project's CoreService.java file.

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

ServiceConnection is used for inter-communication between Activity and Service, as we use ServiceTestCase here (means unit-test service, communication with other components is out-of-scope hence not considered), we don't need a ServiceConnection implementation. The only thing ServiceConnection does is initialize a solid Messenger object so that we could use later, once service is properly created:

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对象后来初始化Messenger的对象。

Also note that you don't need to call ServiceTestCase.startService() in this case, as ServiceTestCase.bindService() will properly start the service (if it is not started yet) and return a IBinder object we need to use to initialize Messenger object later.

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

Say if your IncomingHandler.handleMessage() impelementation in CoreService.java look like this:

... ...

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

... ...

要测试的ServiceTestCase发送消息功能:

To test send message functions in 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不适合于这种情况。考虑使用<一个href="http://developer.android.com/reference/android/test/ActivityInstrumentationTestCase2.html">ActivityInstrumentationTestCase2测试实际活动(其中绑定到您的CoreService,它给你的能力,间接地测试你的服务功能。

If your want to test communication between Activity and Service, then ServiceTestCase is not suitable in this case. Consider using ActivityInstrumentationTestCase2 test the actual Activity (which bound to your CoreService, which gives you ability to indirectly test your Service functions.

这篇关于不是JUnit测试推出Android服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆