我想测试以下(标准?)方案
此方案运行正常。 App中没有问题。
但是现在我也想写自动单元测试,我遇到了问题,处理程序似乎不再发送和处理消息。
我写了像这样的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(..);
此设置正常。该服务运行并执行被调用的方法。但每次使用处理程序发送消息时,都不会执行消息。即,永远不会在Handler上调用handleMessage()。
Message callbackMsg = mCallbackHandler.obtainMessage(CB_CONNECT_TO_NULL_DEVICE, mDevice);
mCallbackHandler.sendMessage(callbackMsg);
调用此代码。 Handler mCallbackHandler是正确的类型。没有错误。什么都没发生。在Handler中没有调用handleMessage()。
首先我认为存在竞争条件,因为Looper在另一个线程上。所以我让测试用例睡了一会儿:
(..)
service.doSomething(..);
Thread.sleep(3000);
Log.d(TAG, "Waking up ...");
callbacks = mockHandler.receivedCallbacks;
assertEquals("one callback", 1, callbacks.size());
但仍然没有。在测试场景中永远不会调用处理程序中的handleMessage()方法。但它在真正的App中运行良好。
在Android JUnit测试中测试处理程序是否存在根本问题?
答案 0 :(得分:0)
问题解决了:
我是如此愚蠢,以至于不在一个单独的线程上启动Handler。因此Handler运行在与JUnit Test相同的线程上。因此,JUnit首先完成,看不到Handler的结果而失败。
当我将Handler放在不同的线程上时,一切都在JUnit测试中正常工作。
答案 1 :(得分:0)
或者,您可以模拟同步处理程序而不是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;
}
});