3

クラスに 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() のみをテストしても問題ありませんか? このようなもの:

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();

これを行うことで、parent() を簡単にテストできます。child_1() と child_2() は、このクラスの他の単体テストで既にテストされているため、不正行為は行われません (少なくとも私はそう考えています。間違っています)。また、実際に chaild_1() と child_2() が複雑なことを行っている場合、このアプローチによりテストが容易になり、時間のかかるコードを重複してチェックする必要がなくなります。

私の質問は、それが正しいアプローチであるかどうかです。そうでない場合、何がマイナス面であり、最も重要なこととして、正しいアプローチは何ですか? 誰かが上記と同じ例で説明できれば、それは素晴らしいことです。

どうもありがとう。

4

2 に答える 2

3

メソッドのオーバーライドは、リスコフの置換原則に違反する可能性が高いため、一般的に避けるべきものだと思います。テスト コードは特別なものではありません。製品コードと同じ厳格な原則に従う必要があります。私が考えることができる唯一の例外は、コンポーネント間の結合が高く、オーバーライドが唯一のオプションであるレガシーコードをテストしている場合です。しかし、新しいコードを書くとき、私には何の理由もありません。

@samlewis は何かに取り組んでいると思います。parent()何らかの理由で分離してテストしたい場合はchild_1()child_2()おそらく に注入される独自のクラスにする必要がありますparent()。クラスより小さいものはテストしないでください。より小さなものをテストする必要がある場合は、抽出したい責任がある可能性があります (単一責任の原則)。

child_1()実際に他のクラスに属しているヒントchild_2()は、それらがパブリックであり、パブリック メソッドparent()がそれを呼び出すことです。パブリック メソッドは通常、非パブリック メソッドのみを呼び出す必要があります (ただし、おそらく例外があります)。

それとも、テストできるように子メソッドを公開しましたか? もしそうなら、この答えを見てください。

于 2013-07-24T06:13:13.880 に答える
1

外部から実際に消費されていますかchild_1()child_2()それともテストできるように公開しましたか?

Torbjörn が指摘しているように、パブリック メソッドが同じインスタンスで他の 2 つのパブリック メソッドを呼び出すことはめったにありません。通常、サブメソッドには、クラスの内部にある動作が含まれており、世界に公開されるべきではありません。それらの名前は、多くの場合、クラスの一般向けの契約とは別のレベルの言語を反映しています。それらは、オブジェクト独自の私的な専門用語で表現されています。

child_1()makeとprivateができると仮定するとchild_2()、それらを明示的にテストする必要はなく、テストによって間接的にテストされparent()ます。

于 2013-07-24T12:09:09.540 に答える