2

これは、単体テストを書いているクラスの簡易版です

class SomeClass {

    void methodA() {
        methodB();
        methodC();
        methodD();
    }

    void methodB() {
        //does something
    }

    void methodC() {
        //does something
    }

    void methodD() {
        //does something
    }
}

このクラスの単体テストを作成する際に、各メソッドで使用される EasyMock を使用してオブジェクトをモックアウトしました。メソッド B、C、D でモック オブジェクトとその期待値を設定するのは簡単でした。しかし、メソッド A をテストするには、さらに多くのモック オブジェクトとその期待値を設定する必要があります。また、メソッド A をさまざまな条件でテストしています。つまり、モック オブジェクトをさまざまな期待値で何度もセットアップする必要があります。

最終的に、私の単体テストは保守が難しくなり、かなり雑然とします。誰かがこの問題に対する良い解決策を持っているか見たかどうか疑問に思っていました.

4

5 に答える 5

3

あなたの質問を正しく理解できれば、これは設計上の問題だと思います。単体テストの良いところは、テストを書くことで、しばしばデザインをより良くする必要があるということです。メソッドのテスト中にあまりにも多くのものをモックする必要がある場合は、多くの場合、クラスを 2 つの小さなクラスに分割する必要があることを意味します。これにより、テストが容易になります (そして、記述、保守、バグ修正、再利用など)。

あなたの場合、メソッド A はメソッド A、B、C よりも高いレベルにあるようです。それを、SomeClass をラップするより高いレベルのクラスに削除することを検討できます。

class HigherLevelClass {
    ISomeClass someClass;

    public HigherLevelClass(ISomeClass someClass)
    {
        this.someClass = someClass;
    }

    void methodA() {
        someClass.methodB();
        someClass.methodC();
        someClass.methodD();
    }
}

class SomeClass : ISomeClass {
    void methodB() {
        //does something
    }

    void methodC() {
        //does something
    }

    void methodD() {
        //does something
    }
}

methodA をテストしているとき、モックする必要があるのは、小さな ISomeClass インターフェイスと 3 つのメソッド呼び出しだけです。

于 2010-06-29T10:51:44.323 に答える
0

共通のセットアップ コードを個別の (場合によってはパラメーター化された) メソッドに抽出し、必要に応じて呼び出すことができます。methodA のテストに他のメソッドのテストとは非常に異なるフィクスチャがある場合、@Before メソッド自体に入れるものがあまりない可能性があるため、テスト メソッド自体からセットアップ ヘルパー メソッドの適切な組み合わせを呼び出す必要があります。それでも少し面倒ですが、あちこちにコードを複製するよりはましです。

使用する単体テスト フレームワークによっては、他のオプションもある場合がありますが、上記はどのフレームワークでも機能するはずです。

于 2010-06-29T08:25:31.477 に答える
0

作成している各テストについて、そのテストにとって価値のある動作を検討してください。動作が依存する設定中のいくつかのコンテキストと、検証したい動作の結果としてのいくつかの結果があります。

関連するコンテキストを設定し、結果を検証し、その他すべてに NiceMocks を使用します。

私は、デフォルトでこのように動作する Mockito (Java) または Moq (.NET) を好みます。これは、Mockito と EasyMock に関する Mockito のページです (Mockito が登場する前は、EasyMock には NiceMock がありませんでした)。

http://code.google.com/p/mockito/wiki/MockitoVSEasyMock

おそらく、EasyMock の NiceMock も同様の方法で使用できます。これがテストのもつれを解くのに役立つことを願っています。いつでも両方のフレームワークをインポートして、それらを一緒に使用したり、必要に応じて段階的に切り替えることができます。

幸運を!

于 2010-06-29T11:56:10.150 に答える
0

メソッド A をさまざまな条件でテストしています。つまり、モック オブジェクトをさまざまな期待値で何度もセットアップする必要があります。

methodA が何をしているか、どのコラボレーター関数を呼び出す必要があるかを気にする場合は、さまざまな期待値を設定する必要があります...このステップをスキップする方法がわかりません!

testLogout の場合、myCollaborator.logout() への呼び出しが予想されます。

多くの/異なる期待を持つ多くのメソッドがある場合は、クラスを共同作業者に分割する場合があります

于 2010-06-30T12:03:27.313 に答える
0

これは脆弱なテストの例です。これは、モックのセットアップがSUTについてあまりにも詳細な知識を持っているためです。

EasyMock はわかりませんが、Moq では void メソッドをセットアップする必要はありません。ただし、Moq では、メソッドは public または protected で virtual でなければなりません。

于 2010-06-29T08:40:36.907 に答える