使用PowerMock& amp;的模拟合作者通过间谍测试方法的Mockito

时间:2013-06-21 21:22:19

标签: java junit mocking mockito powermock

尝试找出做一些看似非常简单的事情的最佳方法:测试一个特定方法是在一个来自被测试类的协作者上调用的。我正在使用Mockito(1.9.5)&带有JDK 6的PowerMock(1.5.1)。

一般方法是通过Mockito spy设置部分模拟,通过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()显然不是。或者别的什么。

绝对愿意接触其他完成同样事情的方法,但想知道我在这里缺少什么。

注意:它看起来不像导入的问题,所以我省略了它们,但如果你认为它们有用,我可以加入它们。

1 个答案:

答案 0 :(得分:0)

我遇到的问题相当简单。在这个问题的第一个版本中也无法看到。

问题是,当我通过produce()设置的Factory WhiteBox.setInternalState()被调用时,该方法没有被正确存根,因此它返回null。因此,当我尝试调用barbar.create()为空:因此NPE。

通过在produce()中正确存根FooGateTest来修复:

when(mockfactory.produce((Class)anyObject())).thenReturn(mockBar);

...并且测试通过,没有错误。