没有单元测试专用方法的情况下如何进行单元测试?

时间:2020-05-10 00:15:25

标签: unit-testing testing junit

我的方法中有很多代码,大致看起来像这样

public void A(boolean f1, boolean f2, boolean f3, int var1, int var2, String var3) {
    if(f1){
        doSomething(var1)
    } else if(f2) {
        doSomethingElse(var1);
        doSomethingMore(var3);
    } else if(f3) {
        doSomethingDifferent();
        doSomethingElse(var2);
        doSomethingDifferentAgain();
    }
}

private void doSomething(int var) { ... }
private void doSomethingElse(int var) { ... }
private void doSomethingMore(String var) { ... }
private void doSomethingDifferent() { ... }
private void doSomethingDifferentAgain() { ... }

现在,如果我将所有这些方法都定义为私有方法,应该如何测试它们?每个方法中的逻辑都是完全封闭的,但是仅测试公用方法就需要在测试中进行比仅对方法进行测试更多的“处理”。

推荐这样测试代码的方法是什么?

1 个答案:

答案 0 :(得分:0)

您应该阅读Parnas 1971

推荐这样测试代码的方法是什么?

TDD的基本主题是我们不测试这样的代码。相反,我们将这样的设计替换为优先考虑可测试性的设计。

宣称是,当您优先考虑可测试性时,您会得到Parnas所谈论的各种模块。因此,将来的更改变得更容易安全地集成到您的代码库中,因此您能够稳定地交付业务价值。

对于TDD从业者来说,复杂的测试(尤其是设置复杂的测试(“给定...”))是一种症状。通常,原因是我们要度量的事物与其他不相关的细节之间存在过多的耦合。响应是重新设计代码,以减少耦合。

所以我们可能会从

private void somethingCoupledToTheWorld(args...) {
    // Complicated things here
}

class DecoupledThing {
    public nowEasyToTest(args...) {
        // Complicated things here
    }
}

private DecoupledThing that = DecoupledThing()

private void somethingCoupledToTheWorld(args...) {
    that.nowEasyToTest(args)
}

最终的设计往往具有更多的模块;尤其是(a)更多的模块可以很好地完成一项工作(SRP),以及(b)更多的模块似乎无法完成自己的工作,只是将工作委托给其他模块。

表达同一想法的另一种方式:我们调整设计,使高风险代码位于易于测试的模块中。

一些好消息:如果您已经对A进行了测试,则仍然可以使用它们。它们有助于确保在将设计重构为支持更集中测试的设计时,代码的行为不会改变。