这是我要测试的课程:
public class MyView extends FrameworkView {
public MyView(Repository repository) {
repository.addEventListener(event -> {
refresh();
});
}
}
及其父母:
public class FrameworkView {
protected final void refresh() {
// do framework magic to refresh the view
}
}
我想单元测试MyView。我可以使用ArgumentCaptor来获取监听器(使用Mockito):
@Test
public void test() {
Repository repository = mock(Repository.class);
MyView instance = new MyView(repository);
ArgumentCaptor<EventListener> listenerArgument = ArgumentCaptor.forClass(EventListener.class);
verify(repository).addEventListener(listenerArgument.capture());
EventListener listener = listenerArgument.getValue();
// call the listener to trigger the refresh() call
listener.handleEvent(null);
// now what?
}
问题是refresh()
方法属于超类(不在我的控制之下),而且它是最终的,并且具有很难验证的副作用。因此,我不知道如何存根或覆盖refresh()
方法,也不知道如何验证其行为。
我现在能想到的唯一解决方案是将refresh()
调用移动到MyView的包私有方法和存根:
public class MyView extends FrameworkView {
public MyView(Repository repository) {
repository.addEventListener(event -> {
doRefresh();
});
}
void doRefresh() {
refresh();
}
}
然后测试将成为:
@Test
public void test() {
Repository repository = mock(Repository.class);
MyView instance = Mockito.spy(new MyView(repository));
....
verify(instance, times(1)).doRefresh();
但我认为这很难看。有没有人有更好的解决方案的想法?