2016-09-09 49 views
0

我必须处理没有测试的遗留应用程序。所以在我开始重构之前,我想确保一切都按照原样进行。Mockito说:“通缉,但未被调用”,但调试测试跳转到该方法

现在想象一下以下情况:

public SomeObject doSomething(final OtherObject x, final String something) { 
    if(x != null) { 
     final String = someOtherMethod(x, something); 
    } 
} 

protected String someOtherMethod(final OtherObject x, final String something) { 
    .... 
} 

现在我要确保受保护的方法被调用以及

所以,我没有这个

@InjectMocks // Yes there is more going on here 
private MyTestObject myTestObject; 

private MyTestObject spy; 

private static final OtherObject VALID_OTHER_OBJECT = new OtherObject(); 

@Before 
public void setup() { 
    this.spy = Mockito.spy(myTestObject); 
} 

@Test 
public void ifOtherObjectIsNotNullExpectSubMethodToBeCalled() { 
    myTestObject.doSomething(VALID_OTHER_OBJECT, null); 
    verify(spy).someOtherMethod(VALID_OTHER_OBJECT, null); 
} 

我得到一个失败的测试和“通缉但不被援引...”为someOtherMethod()。 我跳进调试模式并检查。该方法被称为!

这可能是什么原因造成的?我在这里滥用间谍吗?

编辑:我想拉伸,我知道这不是你通常测试,尤其是因为someOtherMethod(...)有一个非void返回值在这里。但想象一下返回值是void ...

基本上我只是想了解为什么间谍在这里失败。

回答

1

根据its JavadocMockito.spy(object)创建传入对象的副本。调用传入对象的原始方法不会注册在间谍上,因为间谍实例不是同一个对象。

更改myTestObject.doSomething(...)spy.doSomething(...)它应该工作。

替代方法(实现相同目的的不同方法): 考虑在myTestObject上使用@Spy注释。 一定要将MockitoAnnotations.initMocks(this);添加到您的初始化方法(在您的junit测试中)。 @Before@Mock注释也很有用。

+0

它是一个深层复制吗? – Sorona

+0

@Sorona没有在文档中指定,但源代码的快速检查说不。只有浅拷贝。 – Douglas

0

我有一个对象创建另一个和另一个对象进行调用。所以我需要让内部对象使用spied引用。我使用反射并使用Whitebox更新了参考。

TestAddressFragment fragment = spy(new TestAddressFragment()); 
AddressPresenter presenter = fragment.getPresenter(); 
Whitebox.setInternalState(presenter, "view", fragment); 

现在我的片段可以检查它的方法是否被调用。

verify(fragment).showAddress(any(), anyBoolean());