Может ли Android ServiceTestCase<MyService> отправлять сообщения на мой сервис?
Я хочу проверить свой связанный сервис с 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 ответ
Я смог заставить это работать, используя процедуру ниже. Любой желающий может перезвонить, если это неверно, но приведенный выше пример работает (т.е. обработчик MyBindServer получает сообщения)
Кажется, что метод ServiceTestCase bindService() намеревается действовать как локальный сервис. В этом случае цель состоит в том, чтобы протестировать как отдельный процесс, что означает использование следующего вместо 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 обеспечивает согласованные результаты.
Например
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 ()