简体   繁体   English

如何在不实现存根类的情况下为 Mockito 的接口生成间谍?

[英]How can I generate a spy for an interface with Mockito without implementing a stub class?

So I have the following interface:所以我有以下界面:

public interface IFragmentOrchestrator {
    void replaceFragment(Fragment newFragment, AppAddress address);
}

How can I create a spy with mockito that allows me to hook ArgumentCaptor -objects to calls to replaceFragment() ?如何使用mockito创建一个spy ,允许我将ArgumentCaptor对象挂钩到对replaceFragment()调用?

I tried我试过

    IFragmentOrchestrator orchestrator = spy(mock(IFragmentOrchestrator.class));

But mockito complains with "Mockito can only mock visible & non-final classes."但是 mockito 抱怨“Mockito 只能模拟可见和非 final 类。”

The only solution I've come up with so far is to implement an actual mock of the interface before I create the spy .到目前为止,我想出的唯一解决方案是在创建spy之前实现接口的实际模拟。 But that kind of defeats the purpose of a mocking framework:但这违背了模拟框架的目的:

public static class EmptyFragmentOrchestrator implements IFragmentOrchestrator {
    @Override
    public void replaceFragment(Fragment newFragment, AppAddress address) {

    }
}

public IFragmentOrchestrator getSpyObject() {
    return spy(new EmptyFragmentOrchestrator());
}

Am I missing something fundamental?我错过了一些基本的东西吗? I've been looking through the docs without finding anything (but I may be blind).我一直在浏览文档但没有找到任何东西(但我可能是瞎的)。

Spying is when you want to overlay stubbing over an existing implementation.间谍是指您想在现有实现上覆盖存根。 Here you have a bare interface, so it looks like you only need mock :这里你有一个裸接口,所以看起来你只需要mock

public class MyTest {
  @Captor private ArgumentCaptor<Fragment> fragmentCaptor;
  @Captor private ArgumentCaptor<AppAddress> addressCaptor;

  @Before
  public void setup() {
    MockitoAnnotations.initMocks(this);
  }

  @Test
  public void testThing() {
    IFragmentOrchestrator orchestrator = mock(IFragmentOrchestrator.class);

    // Now call some code which should interact with orchestrator 
    // TODO

    verify(orchestrator).replaceFragment(fragmentCaptor.capture(), addressCaptor.capture());

    // Now look at the captors
    // TODO
  }
}

If, on the other hand, you really are trying to spy on an implementation, then you should do that:另一方面,如果你真的想监视一个实现,那么你应该这样做:

IFragmentOrchestrator orchestrator = spy(new IFragmentOrchestratorImpl());

This will call the actual methods on IFragmentOrchestratorImpl , but still allow interception with verify .这将调用IFragmentOrchestratorImpl上的实际方法,但仍允许使用verify进行拦截。

We can do this with org.mockito.Mock annotation我们可以使用org.mockito.Mock注释来做到这org.mockito.Mock

import org.mockito.Mock;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.when;

public class Test {
    @Mock
    private TestInterface mockTestInterface;

    @Test
    public void testMethodShouldReturnTestString() {
        String testString = "Testing...";

        when(mockTestInterface.testMethod()).thenReturn(testString);

        assertThat(mockTestInterface.testMethod(), is(testString));
    }

}

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

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