如何验证函数在Runnable::run()中被调用



有一个函数runInMainThread(Handler mainHandler)的类,它执行一个可运行程序的run():

class AppLifecycleObserver implements LifecycleObserver {
protected Context mAppContext;
AppLifecycleObserver(@NonNull Context appContext) {
mAppContext = appContext;
}
Lifecycle getLifeCycle() {
return ProcessLifecycleOwner.get().getLifecycle();
}
void runInMainThread(Handler mainHandler) {
Runnable myRunnable = new Runnable() {
@Override
public void run() {
getLifeCycle().addObserver(AppLifecycleObserver.this);  // needed to verify it's called
}
};
mainHandler.post(myRunnable);
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart() {
// do something
}
}

在单元测试中,想要验证getLifeCycle().addObserver(AppLifecycleObserver.this);是否被调用。

尝试执行,但出现错误。

@RunWith(RobolectricTestRunner.class)
public class AppLifecycleObserverTest {
private Context mContext;
@Before
public void setup() {
mContext = RuntimeEnvironment.application;
}
@Test
public void test_runInMainThread() throws Exception{
AppLifecycleObserver appLifecycleObserver2 = spy(new AppLifecycleObserver(mContext));
Lifecycle lifecycle = spy(appLifecycleObserver2.getLifeCycle());
doReturn(lifecycle).when(appLifecycleObserver2).getLifeCycle();
Handler handler = mock(Handler.class);
final CountDownLatch finished = new CountDownLatch(1);
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
finished.countDown();
return null;
}
}).when(appLifecycleObserver2).runInMainThread(handler);
appLifecycleObserver2.runInMainThread(handler);
finished.await(2, TimeUnit.SECONDS);
verify(lifecycle).addObserver(appLifecycleObserver2);
}
}

得到错误(似乎没有等待Runnable::run()被调用):

java.lang.Exception: Main looper has queued unexecuted runnables. This might be the cause of the test failure. You might need a shadowOf(getMainLooper()).idle() call.
at org.robolectric.android.internal.AndroidTestEnvironment.checkStateAfterTestFailure(AndroidTestEnvironment.java:470)
at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:548)
at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:252)
at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: Wanted but not invoked:
lifecycleRegistry.addObserver(
AppLifecycleObserver$$EnhancerByMockitoWithCGLIB$$c0ef6f97@62eadb96
);
-> at ppLifecycleObserverTest.test_runInMainThread(AppLifecycleObserverTest.java:133)
Actually, there were zero interactions with this mock.

这个有效,一定有更好的:

@Test
public void test_runInMainThread() throws Exception{

// test the Runnable::run(), the addObserver() should be called
AppLifecycleObserver appLifecycleObserver2 = spy(new AppLifecycleObserver(mContext));
Lifecycle lifecycle = spy(ProcessLifecycleOwner.get().getLifecycle());
doReturn(lifecycle).when(appLifecycleObserver2).getLifeCycle();
Handler handler = mock(Handler.class);
final CountDownLatch finished = new CountDownLatch(1);
Mockito.when(handler.post(Mockito.any(Runnable.class))).thenAnswer(
new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Runnable msg = invocation.getArgumentAt(0, Runnable.class);
msg.run();
finished.countDown();
return null;
}
}
);
appLifecycleObserver2.runInMainThread(handler);
finished.await(2, TimeUnit.SECONDS);
verify(lifecycle).addObserver(appLifecycleObserver2);

}

最新更新