假设我们有方法在类 A 中测试,该方法调用类 B 的方法。为了测试它,我们为 B 创建了 mock,然后验证它是否被调用。 verify(...) 是否足以进行单元测试,或者我需要断言测试方法的实际结果? 以下是澄清我的担忧的简化示例:
public class StringWriterATest {
StringWriterB b = mock(StringWriterB.class);
@Test
public void stringWriterATest() {
StringBuffer sb = new StringBuffer();
StringWriterA a = new StringWriterA();
a.stringWriterB=b;
a.append(sb);
ArgumentCaptor<StringBuffer> argument = ArgumentCaptor.forClass(StringBuffer.class);
verify(b).append(argument.capture());
assertEquals("StringWriterA", ((StringBuffer)argument.getValue()).toString());
//do we really need this or above is enough for proper unit test of method a.append(sb);
//assertEquals("StringWriterA_StringWriterB", sb);
}
}
public class StringWriterA {
public StringWriterB stringWriterB;
public void append(StringBuffer sb) {
sb.append("StringWriterA");
stringWriterB.append(sb);
}
}
class StringWriterB {
public void append(StringBuffer sb) {
sb.append("StringWriterB");
}
}
问候, 最大
最佳答案
永远不需要同时模拟返回值和验证对象。
考虑一下:
StringWriterA
是被测类。因此,您肯定希望使用断言来验证此类的行为。为了做到这一点,你模拟了一个依赖,StringWriterB
.
您不想测试StringWriterB
在你对 StringWriterA
的测试中,因此 StringWriterB
的任何断言测试中的交互在错误的位置。
您必须假设 StringWriterB
表现符合预期。您要么想要验证 StringWriterA
称为 StringWriterB
正确地(使用 verify()
)或您想模拟其预期行为并模拟返回值。
如果您模拟,则验证是隐式的,因为如果未调用该方法,将不会返回模拟的返回值。
在你的例子中,StringWriterA.append()
不返回任何值,因此甚至只能进行验证。那StringWriterB.append()
也可以在 stringWriterBTest
中进行类似的验证测试自己的。
注意:明确测试是件好事。由于从不在框架外调用测试方法,因此永远不需要将它们键入,因此您可以使用比生产代码方法更长的方法名称。一个很好的约定是:
<underTest>Should<Expected>[When]<Condition>()
即
stringWriterAShouldAppendConstantAndDelegateToStringWriterB()
stringWriterAShouldThrowNullPointerExceptionWhenNullArgument()
当您在构建(持续集成)中遇到测试失败时,您不必追查哪里出了问题,方法名称会出现在失败旁边,您可以阅读它以准确了解必须修复的行为.
关于java - Mockito 中模拟方法的单元测试最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5724387/