我有一个正在测试的类,其中包含一个具有内部匿名类的方法。匿名类中的一种方法调用了正在测试的类中的方法,但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()被调用,即使我已经通过在调试器中逐线逐步逐步验证了。我还验证了对依赖项对象的调用返回可观察到的正确内容的正确观察值,而oncomplete()和outermethod()方法确实会被调用。我只是感到困惑为什么摩根托没有这样检测到。
这是它吐出的错误:
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)
我很明显吗?
您在调度程序之间进行更改,因此在测试时可能会引起某些问题(您的代码可能在调用实际方法之前到达verify
方法
检查本文,说明如何使用RXJAVA和MOCKITO测试异步代码
tl; dr
添加一个将所有调度程序设置为trampoline
的TestRule
,以便同步行为:
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();
}
}
};
}
}