【发布时间】:2014-05-02 15:27:06
【问题描述】:
我想测试以下(标准?)场景
- 一个活动使用一个服务对象来做一些事情。
- Service 使用 bindService(..) 绑定到 Activity。
- 服务本身允许通过它在 onBind() 中返回的 Binder 进行访问,该 Binder 提供对服务对象本身的访问(这里的一切都发生在同一个线程上)。
- 在 onServiceConnected(..) 中,活动通过 Binder 访问服务并将处理程序对象交给服务以向活动发送消息。
- 所以通讯是: 活动 -> 通过直接调用服务的服务。和 Service -> Activity 通过 Handler 对象从 Activity 注入到 Service 中
此方案运行良好。应用程序没有问题。
但现在我也想编写自动化单元测试,但遇到了问题,处理程序似乎不再发送和处理消息。
我这样写了一个 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(..);
此设置运行良好。该服务运行并执行调用的方法。但是每次处理程序用于发送消息时,消息永远不会被执行。即,handleMessage() 永远不会在 Handler 上调用。
Message callbackMsg = mCallbackHandler.obtainMessage(CB_CONNECT_TO_NULL_DEVICE, mDevice);
mCallbackHandler.sendMessage(callbackMsg);
调用此代码。处理程序 mCallbackHandler 是正确的类型。没有错误。只是什么都没有发生。处理程序中没有调用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 测试中测试处理程序是否存在根本问题?
【问题讨论】:
-
您回答了自己的问题,所以请接受您自己的回答。
标签: java android unit-testing junit handler