3

EasyMockを使用してかなりの数のモックオブジェクトを作成しました。しかし、部分的なモックを書くのは時間がかかることが多く、「正しい」とは感じません。

私がモックしようとしているクラスには複数の懸念事項が1つにまとめられているため、設計上の誤りだと思います。したがって、懸念事項を分離するために、別個のクラスを作成する必要があります。

どう思いますか?部分的にモックするのは良いことですか、悪いことですか?そして、良い/悪い場合、なぜですか?いくつかのメソッドをモックしたいだけなので、オブジェクトをモックできないことに気付いた場合、何を提案しますか?

4

3 に答える 3

4

定期的に部分的なモックを作成している場合は、少数のクラスに大量の状態と機能がスローされていることを示している可能性があります。これにより、コードの保守と推論がより困難になり、その結果、単体テストが困難になる可能性があります。また、システム内の他のコンポーネントが大規模なクラスの1つに含まれる機能のサブセットを必要としていることが後でわかった場合、コードの重複や循環依存につながる可能性があります。

関連する機能のグループを特定し、それらを個別に単体テストできる小さなヘルパークラスに分割してみてください。これにより、コードが理解しやすくなり、よりきめ細かい単体テストを記述できるようになります。また、将来、さまざまなコンテキストで分割した機能を再利用できるようになる可能性があります。SpringやGuiceなどの依存性注入フレームワークを使用している場合は、アプリケーションの実行時にこれらのオブジェクトを簡単に相互に接続できます。

大規模なクラスをリファクタリングするための最良の方法を見つけることは、経験を通じて学ぶことです。ただし、一般的に、私はクラスが何をしているのかを調べ、処理のさまざまな時点でクラスが果たすさまざまな役割に名前を付けようとします。次に、それらのロールの新しいクラスを作成します。たとえば、サーバーログファイルを読み取り、特定のエントリが見つかったときに管理者にメールを送信するクラスがある場合、ログファイルの解析方法を知っている1つのクラス、トリガーエントリを探す2番目のクラスにリファクタリングすることができます。 、および管理者に通知する方法を知っている3分の1。秘訣は、各クラスに含まれる「知識」の量を制限することです。これにより、一般的な概念を抽象化する機会も得られます。たとえば、クラスをこのように分割すると、

于 2009-11-19T15:07:10.237 に答える
0

私は個人的に部分的なモックのファンではありません。それは、そのときのテストが-ClassAの動作にある程度依存することを意味します。モックClassBのポイントは、そのClassAコラボレーターの実装の詳細に関係なくテストできることです。

「いくつかのメソッドをモックしたいだけ」とはどういう意味か混乱しています。使用しているEasyMockのバージョンは何ですか?通常、実際に呼び出されるメソッドの期待値と戻り値を指定するだけで済みます。それとも、これらのクラスのスタブバージョンを作成しているということですか?

コラボレーターが「複数の懸念事項を1つにまとめている」ことを懸念している場合は、いつでもそのインターフェースをいくつかの異なるインターフェースに分割しようとすることができます。実装クラスはそれらすべてを実装できます。このようにして、実装が単一のクラスである場合でも、単体テストでさまざまなモックを提供できます(インターフェイスごとに1つ)。

于 2009-11-19T14:26:06.137 に答える
0

私の意見は次のとおりです。部分的なモックは、特に次の場合に問題ありません。

•JNIメソッドを呼び出すモックメソッド。

public void methodToTest() {
    int result = invokeLibraryCode();
}

// This method will be mocked
int invokeLibraryCode() {
    // This method is native:
    com.3rdparty.Library.invokeMethod(); 
}

•日付を制御する必要がある一方で、現在の日付で動作するモックメソッド:

public void methodToTest() {
    Calendar cal = getCurrentDate();
}

// This method will be mocked
Calendar getCurrentDate() {
    return Calendar.getInstance();
}

•モックInputStreamProcessおよびその他の抽象クラス:

public void methodToTest(InputStream is) throws IOException {
    int i = is.read(); // is.read() is mocked
}

もちろん、最初の2つのケースをインターフェースでカバーすることもできます(com.3rdparty.Library独自のインターフェースにラップする、実装CurrentDateProviderするなどですが、それは非常に複雑だと思います)。

于 2011-09-08T13:59:23.147 に答える