简体   繁体   English

Mockito:从内部匿名类验证方法调用

[英]Mockito: verifying method call from internal anonymous class

I have a class under test which contains a method which has an inner anonymous class. 我有一个正在测试的类,其中包含一个具有内部匿名类的方法。 One of the methods in the anonymous class calls a method from the class under test, but Mockito doesn't seem to realize this. 匿名类中的一个方法从被测类中调用一个方法,但是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;
    }
}

My test code: 我的测试代码:

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();

    }

}

For some reason that I can't seem to figure out, Mockito can't detect that outerMethod() is being called, even though I have manually verified by stepping through line by line in the debugger. 由于某种原因,我似乎无法弄清楚,即使我已通过在调试器中逐行逐步进行验证,Mockito也无法检测到正在调用externalMethod()。 I have also verified that the call to the dependency object returns the proper observable with the correct content, and the onComplete() and outerMethod() methods do get called. 我还验证了对依赖对象的调用返回了具有正确内容的正确的Observable,并且确实调用了onComplete()和outsideMethod()方法。 I'm just confused why Mockito doesn't detect it as such. 我只是感到困惑,为什么Mockito不会这样检测到它。

This is the error that it spits out: 这是它吐出的错误:

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)

Is there anything obvious I'm missing? 有什么明显的我想念的吗?

You're changing between schedulers so it can cause some issues when testing (your code may reach the verify method before the actual method is invoked 您在调度程序之间进行了更改,因此在测试时可能会引起一些问题(您的代码可能调用实际方法之前就到达了verify方法

Check this article explaining how to test asynchronous code with RxJava and Mockito 查看这篇文章,解释如何使用RxJava和Mockito测试异步代码

TL;DR TL; DR

Add a TestRule that set all schedulers to trampoline so it behaves synchronously: 添加一个将所有调度程序都设置为trampolineTestRule ,使其行为同步:

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();
        }
      }
    };
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM