0

我是使用 Mockito 进行 JUnit 测试的新手。我正在努力找出“测试逻辑”问题,其中之一是stub 的深度

让我举一个简单的例子:

首先,假设这是要测试的类:

Class ToBeTested {
    public int a1() {}
    public int a2() {}
    public int a3() {}

    public int A() {
        return a1() + a2() + a3();
    }

    public int B() {
        temp = A();
        return temp++;
    }
}

当我尝试编写 JUnit 测试时,我不确定如何存根这些方法。例如:

@Test
public void testB() {
    ToBeTested mockedTBT = mock(ToBeTested.class);

    /*
     *Problem here: How Deep to stub?
     */

    //shallow stubbing
    BDDMockito.given(mockedTBT.A()).willReturn(6);

    //deep stubbing
    BDDMockito.given(mockedTBT.a1()).willReturn(1);
    BDDMockito.given(mockedTBT.a2()).willReturn(2);
    BDDMockito.given(mockedTBT.a3()).willReturn(3);

    int expected = 7;
    int result= mockedTBT.B();

    assertEquals(expected, result);
}

在这种情况下,我应该使用浅存根还是深存根?或者我可以遵循任何规则来编写合理的测试吗?

提前感谢您的帮助。

4

2 回答 2

2

您应该模拟测试您关注的行为所需的最少数量。

在上面的示例中,您似乎关心B()调用A()并返回一个递增的值。因此,只需模拟来自A().

您稍后可能希望测试 的功能A(),在这种情况下,您可以选择模拟A()调用的其他方法。

于 2013-07-16T14:51:49.177 回答
2

如果你真的在做单元测试,那么理想情况下你不应该存根被测类(被测系统)中的任何方法——而应该只模拟协作者类。在您的情况下,这可能暗示了一种“代码气味”,表明您可能希望将您的类划分为多个类,每个类都有一组明确定义的职责。

如果您认为该类不需要拆分,那么对于单元测试,您需要将其视为一个黑盒,并且只需考虑所有可能的不同类型的输入条件,并将其从外部调用驱动到您的类而不是嘲笑内部部分。我喜欢Mockito 和嘲笑,但使用它有正确和错误的地方。

于 2013-07-16T15:20:53.213 回答