如何验证构造函数中的方法调用?

时间:2014-05-29 11:47:16

标签: java unit-testing junit mockito powermock

我有一个构造函数,它调用两个方法。它们都是无效的,我只想验证它们是否被调用。

Foo.java

public class Foo {

    public Foo(String name, Object obj) {
         init(name);
         doSomething(obj);
    }
}

FooTest.java

@Test
public void constructor_test throws Exception {
    Foo foo = Mockito.mock(Foo.class);
    PowerMockito.whenNew(Foo.class).withAnyArguments().thenReturn(foo);
    Foo f = new Foo("name");
    verify(f).init(Mockito.anyString()); 
    verify(f).doSomething(Mockito.any(Object.class)); 
}

单元测试失败,并显示一条消息,表示与模拟 foo.init(); 之间存在零交互。

如何验证构造函数中的方法调用?

1 个答案:

答案 0 :(得分:4)

您是否可以通过检查Foo的状态进行测试?

是的,你可以调用一些外部可见的getName()函数并验证在构造函数中是否正确设置了名称?这比检查私有方法的调用更好,因为只要行为和外部状态相同,你就可以重构类的内部工作而不必更改测试。

如果您发现自己想要检查单元测试中是否已调用私有方法,那么这是一种气味,我应该重新考虑您的方法。有些other questionsalready covered个相似的区域。

如果这些方法与某些外部组件交互,那么您可以像通常使用任何方法一样模拟这些组件,然后按照您的预期验证交互。这种交互是在一种方法中发生还是在内部发生,应该是Foo类的实现细节,在外部你不应该关心。

感觉您所需的方法会导致极其脆弱的测试,随着Foo的实施发生变化,需要经常更改。

至于你的实际问题,我不确定你能做你想做的事情,根据我的理解,你的Foo不是真正的' Foo但是模拟Foo所以真正的构造函数不会被调用。

如果你能够通过创建一个' PartialMock'并将其委托给基础类。我只对Mockito有一点经验,但我认为这种方法可能适用于我熟悉的其他一些(.NET)模拟框架,虽然我还没试过,但它可能会给你一些额外的词来提升你的谷歌foo。