如何对调用私有方法链的方法进行单元测试?

时间:2014-02-13 02:29:29

标签: java unit-testing junit jmock

    public void publicMethod() {
        privateMethod1();
        privateMethod2();
        privateMethod3();
        privateMethod4();
    }

    private void privateMethod4() {
        anotherPrivateMethodOrServiceCall();
        // ....
    }

    private void privateMethod3() {
        anotherPrivateMethodOrServiceCall();
        // ....
    }

    private void privateMethod2() {
        anotherPrivateMethodOrServiceCall();
        // ....
    }

    private void privateMethod1() {
        anotherPrivateMethodOrServiceCall();
        // ....
    }

私有方法不能单独测试而不使其默认(这有点难看)。 如果我从公共方法测试它,它总是导致超级大的嘲弄和断言。维持如此大的测试用例是一件痛苦的事。处理这个问题的任何其他好方法或做法?感谢。

// long list of service mocking

@Test
public void testPublicMethod() {
    context.checking(new Expectations() {{
    // super long list of result mocking
    }});
    // ...
    // super long list of assertions
    assertEquals(....);
}

1 个答案:

答案 0 :(得分:1)

我非常了解Java或Java中的单元测试,所以我在这里观察的是一般的纯粹的一般对单元测试。

  • 看起来你的班级内部做得太多了。如果您需要通过单个公共呼叫进行4次私有方法调用,那么您很可能处于违反SRP的区域(并非此规则不是不可侵犯的,但它是设计的良好指标)气味)

  • 现在我们没有太多关于你的“外部”类正在做什么的上下文,但是根据所提供的信息,也许你可以考虑重构这四个私有方法中的每一个所完成的工作分为4个单独的,您可以将它们作为依赖项提供给您的主类;然后,您将测试方法更改为具有多个较小的测试,每个测试只检查是否调用了特定的依赖项

例如,您的方法名称可能类似于

PublicMethod_InvokesService1(){}
PublicMethod_InvokesService2(){}
PublicMethod_InvokesService3(){}
PublicMethod_InvokesService4(){}

这意味着您可以避免在单个方法中使用所有那些巨大的模拟/断言链。

  • 您可能认为这是天真的,因为 - 操作的顺序如何 - 确实它太乱了以确保调用的顺序是正确的,如何通过Mocks将返回值从Method1传递到方法2等等。

  • 在这种情况下,如果需要以严格的顺序调用这些服务,那么您也可以考虑使用层次结构而不是依赖的平面列表

,而不是

PublicClass depends on Service 1 (depends on Service2,3 and 4)

你有

PublicClass depends on Service 1 (depends on Service2 (depends on Service 3 (depends on Service 4))))
  • 这意味着操作顺序为N / A;来自公共关闭的每个服务仅调用单个依赖项,这意味着您不必担心订单。实际上,在编写公共方法之前,您已经在结构上强制执行逻辑操作顺序。

只是我的2c。