试图找出做一些看起来很简单的事情的最佳方法:测试是否在被测试类的协作器上调用了特定方法。我正在使用Mockito(1.9.5)&PowerMock(1.5.1)与JDK 6。
一般的方法是通过Mockito spy
设置部分mock,通过PowerMock WhiteBox
方法设置内部状态,然后调用我正在测试的方法:creatFoo()
。
尽可能简化代码,同时仍能理解我所学的要点
public class FooGate {
BlackBox.Factory factory;
BlackBox.Bar bar;
public void createFoo(Foo foo) {
bar = factory.produce(BlackBox.Bar.class);
bar.create(bbFoo);
}
...
}
以下是不起作用的测试:
@RunWith(PowerMockRunner.class)
@PrepareForTest(FooGate.class)
public class FooGateTest {
@Test
public void test() {
FooGate testGate = Mockito.spy(new FooGate());
BlackBox.Factory mockfactory = mock(BlackBox.Factory.class);
BlackBox.Bar mockBar = mock(BlackBox.Bar.class);
WhiteBox.setInternalState(testGate, BlackBox.Factory, mockFactory);
WhiteBox.setInternalState(testGate, BlackBox.Bar, mockBar);
Foo foo = new Foo();
foo.setSetting("x");
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) {
... do stuff ...
}
}).when(mockBar).create(any(Foo.class));
// NPE here: seems like bar is null in testGate.
testGate.createFoo(foo);
assertStuff(...);
}
}
如果我删除Factory
的WhiteBox.set…,我会在factory.produce()
上获得一个NPE。所以,这似乎奏效了。
但doAnswer()
显然不是。或者其他什么。
当然,我对其他能完成同样任务的方法持开放态度,但我想知道我在这里缺少了什么。
注意:看起来这不是进口的问题,所以我省略了它们,但如果你认为它们可能有用,我可以包括它们
我遇到的问题相当简单。在这个问题的第一个版本中也不可能看到。
问题是,当调用我通过WhiteBox.setInternalState()
设置的Factory
上的produce()
时,该方法没有正确地存根,因此返回null。所以当我尝试调用bar.create()
时,bar
为空:因此为NPE。
通过在FooGateTest
:中正确存根produce()
修复
when(mockfactory.produce((Class)anyObject())).thenReturn(mockBar);
测试通过,没有错误。