我有一个正在测试的类,它包含一个具有内部匿名类的方法。匿名类中的一个方法从被测试的类中调用一个方法,但Mockito似乎没有意识到这一点。
public class ClassUnderTest {
Dependency dependency;
public ClassUnderTest(Dependency d) {
dependency = d;
}
public void method() {
dependency.returnsObservable().observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io()).subscribe(new Observer<SupportClass> {
/* Other methods omitted */
public void onComplete() {
outerMethod();
})
}
public void outerMethod() {
blah;
}
}
我的测试代码:
public class TestClass {
ClassUnderTest underTest;
Dependency dependency;
@Before
public void setUp() throws Exception {
dependency = Mockito.mock(Dependency.class);
underTest = Mockito.spy(new ClassUnderTest(dependency));
}
@Test
public void method() throws
Mockito.when(dependency.returnObservable()).thenReturn(Observable.just(new SupportClass());
Mockito.doNothing().when(underTest).outerMethod();
underTest.method();
Mockito.verify(underTest).outerMethod();
}
}
由于某种原因我似乎无法弄明白,即使我已经通过调试器中的逐行逐步手动验证,Mockito也无法检测到正在调用outerMethod()。我还验证了对依赖项对象的调用返回了具有正确内容的正确observable,并且调用了onComplete()和outerMethod()方法。我很困惑为什么Mockito没有检测到它。
这是它吐出的错误:
Wanted but not invoked:
classUnderTest.outerMethod();
-> at (file and line number)
However, there was exactly 1 interaction with this mock:
classUnderTest.method();
-> at (file and line number)
我有什么明显的遗失吗?
答案 0 :(得分:2)
您在计划程序之间进行了更改,因此在测试时可能会导致一些问题(您的代码可能会在调用实际方法之前到达verify
方法
检查this article,解释如何使用RxJava和Mockito
测试异步代码<强> TL; DR 强>
添加TestRule
,将所有调度程序设置为trampoline
,使其同步运行:
public class TrampolineSchedulerRule implements TestRule {
@Override
public Statement apply(final Statement base, Description d) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
RxJavaPlugins.setIoSchedulerHandler(
scheduler -> Schedulers.trampoline());
RxJavaPlugins.setComputationSchedulerHandler(
scheduler -> Schedulers.trampoline());
RxJavaPlugins.setNewThreadSchedulerHandler(
scheduler -> Schedulers.trampoline());
RxAndroidPlugins.setInitMainThreadSchedulerHandler(
scheduler -> Schedulers.trampoline());
try {
base.evaluate();
} finally {
RxJavaPlugins.reset();
RxAndroidPlugins.reset();
}
}
};
}
}