Java 如何在Android JUnit测试中测试来自服务的处理程序回调?

Java 如何在Android JUnit测试中测试来自服务的处理程序回调?,java,android,unit-testing,junit,handler,Java,Android,Unit Testing,Junit,Handler,我想测试以下标准?情景 活动使用服务对象执行某些操作。 已使用bindService将服务绑定到活动。。。 服务本身允许通过一个绑定器进行访问,它在onBind中返回该绑定器,该绑定器允许访问服务对象本身。在这里,在同一线程上发生的一切。 在OnService连接中。。活动通过活页夹访问服务,并将处理程序对象交给服务以向活动发送消息。 因此,通信是: 活动->通过直接呼叫服务提供服务。和服务->活动,通过从活动注入服务的处理程序对象 这个场景很好用。应用程序中没有问题 但是现在我还想编写自动单元

我想测试以下标准?情景

活动使用服务对象执行某些操作。 已使用bindService将服务绑定到活动。。。 服务本身允许通过一个绑定器进行访问,它在onBind中返回该绑定器,该绑定器允许访问服务对象本身。在这里,在同一线程上发生的一切。 在OnService连接中。。活动通过活页夹访问服务,并将处理程序对象交给服务以向活动发送消息。 因此,通信是: 活动->通过直接呼叫服务提供服务。和服务->活动,通过从活动注入服务的处理程序对象 这个场景很好用。应用程序中没有问题

但是现在我还想编写自动单元测试,我遇到了一个问题,处理程序似乎不再发送和处理消息了

我写了一个类似这样的Android JUnit测试

public class EpcServiceMockTest extends ServiceTestCase<EpcServiceMock> {...}
public void testConnectToDevice() {
    Intent serviceIntent = new Intent(getContext(), EpcServiceMock.class);
    IBinder binder = bindService(serviceIntent);
    EpcServiceHandlerMock mockHandler = new EpcServiceHandlerMock(this);
    EpcServiceMock service = (EpcServiceMock) ((EpcServiceBase.LocalBinder) binder).getService(mockHandler);
service.doSomething(..);
这个装置很好用。服务运行并执行被调用的方法。但每次使用处理程序发送消息时,消息都不会执行。i、 e.不会对处理程序调用handleMessage

    Message callbackMsg = mCallbackHandler.obtainMessage(CB_CONNECT_TO_NULL_DEVICE, mDevice);
    mCallbackHandler.sendMessage(callbackMsg);
此代码称为。处理程序mCallbackHandler的类型正确。没有错误。只是什么都没发生。处理程序中没有对handleMessage的调用

    Message callbackMsg = mCallbackHandler.obtainMessage(CB_CONNECT_TO_NULL_DEVICE, mDevice);
    mCallbackHandler.sendMessage(callbackMsg);
首先,我认为存在竞争条件,因为活套在另一个线程上。因此,我让测试用例休眠一段时间:

(..)
service.doSomething(..);
Thread.sleep(3000);
Log.d(TAG, "Waking up ...");
callbacks = mockHandler.receivedCallbacks;
assertEquals("one callback", 1, callbacks.size());
但还是什么都没有。在测试场景中从未调用处理程序中的handleMessage方法。但它在真正的应用程序中运行良好

在Android JUnit测试中测试处理程序是否存在根本问题?

问题已解决:

我太愚蠢了,没有在单独的线程上启动处理程序。因此,处理程序与JUnit测试在同一线程上运行。因此,JUnit首先完成,没有看到处理程序的结果,因此失败

当我将处理程序放在另一个线程上时,JUnit测试中一切都正常。

问题解决:

我太愚蠢了,没有在单独的线程上启动处理程序。因此,处理程序与JUnit测试在同一线程上运行。因此,JUnit首先完成,没有看到处理程序的结果,因此失败


当我将处理程序放在另一个线程上时,JUnit测试中一切都正常。

或者,您可以模拟同步处理程序而不是线程。sleep

Mockito.when(testHandler.post(any(Runnable.class))).thenAnswer(new Answer<Object>() {
        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
            ((Runnable) invocation.getArgument(0)).run();
            return null;
        }
    });

或者,您可以模拟同步处理程序,而不是Thread.sleep

Mockito.when(testHandler.post(any(Runnable.class))).thenAnswer(new Answer<Object>() {
        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
            ((Runnable) invocation.getArgument(0)).run();
            return null;
        }
    });

你回答了你自己的问题,所以请接受你自己的答案。你回答了你自己的问题,所以请接受你自己的答案。