java - Mockito 中模拟方法的单元测试最佳实践

标签 java junit tdd mockito

假设我们有方法在类 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/

相关文章:

java - 检测微服务内流程的完成情况

java - 哪个单元测试框架用于 JavaFX 应用程序?

java - 如何让测试等待 Vert.x Verticle 部署完成

c# - MS 测试断言检查

java - 求和科学小数的错误

java - 公共(public)方法与公共(public) API

ruby - 在 rspec 中测试递归 IO 提示

c# - 使用 Moq 验证引用参数的值

java - 如何在覆盖文件之前检查文件是否为空?

ant - 如何使用 Ant 在 JUnit3 测试类上运行自定义 JUnit4 Runner?