我是单元测试的新手,我坚持测试以下方法:
fun freeze(view: View) {
view.isClickable = false
handler.postDelayed({
view.isClickable = true
}, CLICK_TIMEOUT)
}
以下是我已经拥有的内容:
@Test
fun freeze() {
var view = mock<View>()
viewUtil.freeze(view)
assertFalse(view.isClickable)
}
但现在我需要在CLICK_TIMEOUT
之后测试该视图是否可以点击。
我该如何实施这种测试?
答案 0 :(得分:4)
如果你能够模拟Handler
实例,你可以这样做:
Handler mockHandler = mock(Handler.class); when(mockHandler.postDelayed(any(Runnable.class), anyLong())).thenAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { invocation.getArgumentAt(0, Runnable.class).run(); return null; } });
答案 1 :(得分:0)
我在模拟最终的postDelayed
方法时遇到了麻烦,但是由于它归结为非最终的sendMessageAtTime
,所以我对此进行了模拟。使用spy
避免模拟其他Handler
方法。
spyHandler = spy(new Handler(getMainLooper()));
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Message message = invocation.getArgument(0);
message.getCallback().run();
return true;
}
}).when(spyHandler).sendMessageAtTime(any(Message.class), anyLong());
答案 2 :(得分:0)
我遇到了同样的问题,但就我而言,我应该使用实际的Runnable
来运行实际的delay
,因此基于@mrtowel答案,我最终得到了以下代码:
Handler handler = mock(Handler.class);
when(handler.postDelayed(any(Runnable.class), anyLong())).thenAnswer((Answer) invocation -> {
new Thread(() -> {
try {
Thread.sleep(invocation.getArgument(1));
} catch (InterruptedException e) {
e.printStackTrace();
}
((Runnable) invocation.getArgument(0)).run();
}).start();
return null;
});