在您不想测试的类中覆盖方法是一种好方法吗?

时间:2013-07-23 23:19:13

标签: java unit-testing testing junit tdd

假设我的班级有3种方法:

public void parent() throws Exception {}
public String child_1(String arg_1) throws IOException {}
public boolean child_2(String arg_1, String arg_2) throws SQLException {}

parent()调用child_1()child_2(),例如:

public void parent() throws Exception {
    // Do some complicated stuff

    child_1("str1");

    // More stuff

    child_2("str1", "str2");

    // More stuff
}

现在,如果我已经测试了child_1()和child_2()并且我只想测试parent(),是否可以覆盖child_1()和child_2()并仅测试parent()?< / strong>这样的事情:

MyClass myClass = new MyClass() {
    @Override
    public String child_1(String arg_1) throws IOException {
        return "expected_string_to continue_execution";
    }

    @Override
    public boolean child_2(String arg_1, String arg_2) throws SQLException {
        return true;    // return expected boolean result to continueexecution;
    }
};

myClass.parent();

通过这样做,我可以轻松地测试我的父(),因为child_1()和child_2()已经在这个类的其他单元测试中进行了测试,它没有做任何作弊(至少这是我的想法,请更正我,如果我错了)。此外,在现实世界中,如果chaild_1()和child_2()正在做一些复杂的事情,这种方法使测试变得容易,我们不会冗长地检查耗时的代码。

我的问题是,这是否正确?如果不是,那么缺点是什么,最重要的是,什么是正确的方法? 如果有人可以用相同的上述例子解释,那将是非常棒的。

非常感谢。

2 个答案:

答案 0 :(得分:3)

我会说覆盖方法是你应该避免的,因为它很可能违反了Liskov substitution principle。测试代码并不特别:它应遵循与生产代码相同的严格原则。我能想到的唯一例外是,如果您正在测试组件之间具有高耦合的遗留代码,那么覆盖是唯一的选择。但是在编写新代码时我没有看到任何理由。

我认为@samlewis正在做点什么:如果你觉得你想因某些原因而孤立地测试parent(),那么child_1()child_2()应该属于自己的类注入parent()。避免测试小于类的任何东西。如果你需要测试更小的东西,你可能有责任想要被提取(Single responsibility principle)。

child_1()child_2()实际上属于其他类的提示是它们是公共的,公共方法parent()会调用它。公共方法通常只应调用非公共方法(尽管可能有例外)。

或者您是否将子方法公开,以便您可以测试它们?如果是这样,请查看this answer

答案 1 :(得分:1)

child_1()child_2()是否真的从外部消费,或者您是否将其公开以便进行测试?

正如Torbjörn指出的那样,很少见到一个公共方法在同一个实例上调用另外两个公共方法。子方法通常包含类内部的行为,不应暴露给世界。他们的名字通常反映的是另一种语言水平,而不是公众面对的合同 - 他们用对象自己的私人行话来表达。

假设您可以将child_1()child_2()设为私有,则无需明确测试它们,它们将通过parent()测试间接测试。