Может ли Android ServiceTestCase <MyService>отправлять сообщения на мой сервис? - PullRequest
5 голосов
/ 07 июля 2011

Я хочу проверить свой связанный сервис с ServiceTestCase.Тестирование состоит из привязки к MyBindServer и отправки сообщения.Просматривая журналы, вы можете увидеть, что служба запускается при вызове onBind (), и сообщение отправляется из testAHello (), но handleMessage () сервера никогда не вызывается.

Из журналов:

I/TestRunner( 2099): started: testAHello(com.inthinc.mybindserver.test.MyBindServerTest)
I/MyBindServerTest( 2099): setUp()
I/MyBindServer( 2099): onBind, action=com.inthinc.mybindserver.START
I/MyBindServerTest( 2099): testAHello
I/MyBindServerTest( 2099): sending SAY_HELLO
[here is where I expect to see the output from handleMessage()]
I/MyBindServerTest( 2099): tearDown()
I/TestRunner( 2099): finished:testAHello(com.inthinc.mybindserver.test.MyBindServerTest)
I/TestRunner( 2099): passed: testAHello(com.inthinc.mybindserver.test.MyBindServerTest)

Вот код для MyBindServer.java:

package com.inthinc.mybindserver;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.util.Log;

public class MyBindServer extends Service {
    static final String TAG = "MyBindServer";
    public static final int MSG_SAY_HELLO = 1;
    final Messenger mMessenger = new Messenger(new IncomingHandler());

    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            Log.i(TAG, String.format("handleMessage, what=%d", msg.what));
            switch (msg.what) {
                case MSG_SAY_HELLO:
                    Log.i(TAG, "hello");
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, String.format("onBind, action=%s", intent.getAction()));
        return mMessenger.getBinder();
    }

}

Вот код для MyBindServerTest.java:

package com.inthinc.mybindserver.test;

import com.inthinc.mybindserver.MyBindServer;

import android.content.Intent;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.test.ServiceTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;

public class MyBindServerTest extends ServiceTestCase<MyBindServer> {
    private static final String TAG = "MyBindServerTest";
    Messenger mServer = null;

    public MyBindServerTest() {
        super(MyBindServer.class);
    }

    public MyBindServerTest(Class<MyBindServer> serviceClass) {
        super(serviceClass);
    }

    @Override
    public void setUp() {
        try {
            super.setUp();
            Log.i(TAG, "setUp()");
            Intent bindIntent = new Intent("com.inthinc.mybindserver.START");
            IBinder binder = bindService(bindIntent);
            assertNotNull(binder);
            mServer = new Messenger(binder);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void tearDown() {
        try {
            super.tearDown();
            Log.i(TAG, "tearDown()");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @SmallTest
    public void testAHello() {
        Log.i(TAG, "testAHello");
        assertNotNull(mServer);
        Message msg = Message.obtain(null, MyBindServer.MSG_SAY_HELLO);
        Log.i(TAG, "sending SAY_HELLO");
        try {
            mServer.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

}

1 Ответ

3 голосов
/ 30 июля 2011

Я смог заставить это работать, используя процедуру, приведенную ниже. Любой желающий может перезвонить, если это неверно, но приведенный выше пример работает (т.е. обработчик MyBindServer получает сообщения)

Кажется, что метод bindService () ServiceTestCase намеревается действовать как локальный сервис. В этом случае цель состоит в том, чтобы протестировать как отдельный процесс, что означает использование следующего вместо bindService ServiceTestCase:

Intent bindIntent = new Intent(<registered intent>); //Where registered intent is declared in the manifest file
getContext().bindService(bindIntent,mConn,Context.BIND_AUTO_CREATE);

, где mConn - это объект ServiceConnection, реализованный для выполнения того, что требуется вашему тесту, в вышеописанном случае установите mServer.

С учетом вышеизложенного метод handleMessage () MyBindServer вызывается для теста testAHello ().

ОБНОВЛЕНИЕ: я заметил, что в зависимости от того, насколько быстро выполняется тестовая обработка, teardown () может быть вызван до того, как привязка будет готова к использованию. В приведенном выше случае добавление управляющих переменных для регулирования потока программы на основе вызова onServiceConnected в mConn обеспечивает согласованные результаты.

1012 * Е.Г. *

protected boolean bound = false;
protected boolean processed = false;
private ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className,
            IBinder service) {
        Log.i(TAG,"Service conn");

        mServer = new Messenger(service);
        if(mServer != null
                && mServer != null){
            bound = true;
        }
        processed = true;
    }

@Override
public void onServiceDisconnected(ComponentName name) {
    // TODO Auto-generated method stub
    Log.i(TAG,"Service Disconn");
}
};

Затем добавьте:

while(!processed){      
try {
   Thread.sleep(1000);
   } catch (InterruptedException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
   }
}   

для проверкиAHello ()

...