Java でモック オブジェクトを作成するための最適なフレームワークは何ですか? なんで?各フレームワークの長所と短所は何ですか?
14 に答える
私はMockitoを使って大成功を収めました。
JMockとEasyMockについて学習しようとしたとき、学習曲線が少し急であることがわかりました(多分それは私だけですが)。
Mockitoは、構文がシンプルでクリーンで、すぐに理解できたので気に入っています。最小限の構文は、一般的なケースを非常にうまくサポートするように設計されていますが、もっと複雑なことをする必要が数回ありましたが、必要なものがサポートされており、理解しやすいことがわかりました。
Mockitoホームページの(要約)例を次に示します。
import static org.mockito.Mockito.*;
List mockedList = mock(List.class);
mockedList.clear();
verify(mockedList).clear();
それよりも簡単になることはありません。
私が考えることができる唯一の大きな欠点は、静的メソッドをモックしないことです。
JMockitプロジェクト サイトには、現在のモック ツールキットの比較情報が多数含まれています。
特に、EasyMock、jMock、Mockito、Unitils Mock、PowerMock、そしてもちろん JMockit をカバーする機能比較マトリックスを確認してください。可能な限り正確かつ最新の状態に保つように努めています。
私はJMockitで成功を収めてきました。
それはかなり新しいので、少し生で文書化されていません。ASMを使用してクラスバイトコードを動的に再定義するため、静的、プライベート、コンストラクター、静的初期化子を含むすべてのメソッドをモックアウトできます。例えば:
import mockit.Mockit;
...
Mockit.redefineMethods(MyClassWithStaticInit.class,
MyReplacementClass.class);
...
class MyReplacementClass {
public void $init() {...} // replace default constructor
public static void $clinit{...} // replace static initializer
public static void myStatic{...} // replace static method
// etc...
}
記録/再生シナリオも可能にするExpectationsインターフェイスがあります。
import mockit.Expectations;
import org.testng.annotations.Test;
public class ExpecationsTest {
private MyClass obj;
@Test
public void testFoo() {
new Expectations(true) {
MyClass c;
{
obj = c;
invokeReturning(c.getFoo("foo", false), "bas");
}
};
assert "bas".equals(obj.getFoo("foo", false));
Expectations.assertSatisfied();
}
public static class MyClass {
public String getFoo(String str, boolean bool) {
if (bool) {
return "foo";
} else {
return "bar";
}
}
}
}
欠点は、Java5/6が必要なことです。
Groovy を使用したテストもご覧ください。Groovy では、'as' 演算子を使用して Java インターフェイスを簡単にモックできます。
def request = [isUserInRole: { roleName -> roleName == "testRole"}] as HttpServletRequest
この基本的な機能とは別に、Groovy は強力なMockFor
やStubFor
クラスなど、モッキングの面でさらに多くの機能を提供します。
EasyMockでモックを使い始めました。理解するのは簡単ですが、リプレイのステップはちょっと面倒でした。Mockitoはこれを削除し、読みやすさが主な目標の 1 つであったように見えるため、よりクリーンな構文も備えています。ほとんどの開発者は、既存のコードを作成するのではなく、既存のコードを読んで保守することに時間を費やしているため、これがどれほど重要かをいくら強調してもしきれません。
もう 1 つの良い点は、インターフェイスと実装クラスが同じ方法で処理されることです。EasyMock では、EasyMock クラス拡張を使用することを覚える (および確認する) 必要がありますが、これとは異なります。
私は最近、 JMockitをざっと見てみました。機能の洗濯物リストはかなり包括的ですが、これの代償は、結果のコードの読みやすさと、より多くのコードを書かなければならないことだと思います。
私にとって、Mockito は、書きやすく読みやすく、ほとんどのコードが必要とする状況の大部分に対処できるという点で、スイート スポットに当たります。PowerMockでMockitoを使用するのが私の選択です。
考慮すべきことの 1 つは、自分で開発している場合、または小さな緊密なチームで開発している場合に選択するツールは、さまざまなスキル レベルの開発者がいる大企業にとって最適ではない可能性があるということです。後者の場合は、読みやすさ、使いやすさ、シンプルさをさらに考慮する必要があります。多くの人が最終的にそれを使用しないか、テストを維持しない場合、究極のモッキング フレームワークを取得しても意味がありません。
私たちはEasyMockとEasyMockClassExtensionを仕事で多用しており、かなり満足しています。それは基本的にあなたが必要とするすべてをあなたに与えます。ドキュメントを見てください。EasyMockのすべての機能を示す非常に優れた例があります。
私は早くからJMockを使っていました。前回のプロジェクトで Mockito を試してみましたが、気に入りました。より簡潔に、よりクリーンに。PowerMock は、静的コードのモック、インスタンス作成のモック、最終クラスとメソッドのモックなど、Mockito にはないすべてのニーズをカバーします。だから私は自分の仕事をするために必要なものをすべて持っています。
期待値を設定できる JMock が好きです。これは、いくつかのモック ライブラリで見つかったメソッドが呼び出されたかどうかを確認することとはまったく異なります。JMock を使用すると、非常に洗練された期待値を記述できます。jmock のチートシートを参照してください。
はい、Mockito は素晴らしいフレームワークです。hamcrestおよびGoogle guiceと一緒に使用して、テストをセットアップします。
Mockitoには、スタブメソッド、引数の照合(anyInt()やanyString()など)、呼び出し回数の確認(times(3)、atLeastOnce()、never())などのオプションもあります。
また、Mockitoはシンプルでクリーンであることがわかりました。
Mockitoについて私が気に入らないことの1つは、静的メソッドをスタブ化できないことです。
私は JMock を通じてモックを使い始めましたが、最終的に EasyMock を使用するように移行しました。EasyMock はまさにそれであり、より簡単で、より自然に感じられる構文を提供しました。それ以来、切り替えていません。