Mockito vs Jmockitの比較 - なぜMockitoはJmockitよりも優れているのですか? [閉まっている

StackOverflow https://stackoverflow.com/questions/4105592

質問

私は自分のプロジェクトに使用するmockingフレームワークを調査し、それを絞り込みました jmockitモキト.

私はそれに気づきます モキト 投票された」Javaに最適なモックフレームワーク「Stackoverflowで。
機能を比較すること jmockit「s」モッキングツール比較マトリックス「それはそうです jmockit 複数の異なる機能があります。

誰かが何について特定の情報を持っていますか(意見ではありません) モキト で達成できないことを行うことができます jmockit およびその逆?

役に立ちましたか?

解決

2019年9月の更新: 唯一の Spring Bootで(デフォルトで)サポートされているモッキングフレームワークモキト. 。 Springを使用する場合、答えは非常に明白です。


競争は間にあると思います jmockitPowerMock, 、 それから モキト.

「Plain」JMockとEasyMockは、プロキシとCGLIBのみを使用し、新しいフレームワークのようなJava 5インストゥルメンテーションを使用しないため、私は去ります。

Jmockは、4年以上安定したリリースもありませんでした。 JMock 2.6.0は、RC1からRC2に2年間、実際にリリースされる2年前に2年かかりました。

プロキシ&cglib対計器について:

(EasyMockとJMock)は、java.lang.reflt.proxyに基づいており、インターフェイスを実装する必要があります。さらに、CGLIBサブクラス生成を通じてクラス用のモックオブジェクトの作成をサポートしています。そのため、クラスは最終的なものではなく、過度に配置可能なインスタンスのみのメソッドのみをock笑することができます。最も重要なことは、これらのツールを使用する場合、テスト中のコードの依存関係(つまり、テスト中の特定のクラスが依存する他のクラスのオブジェクト)をテストによって制御する必要があるため、モックインスタンスをクライアントに渡すことができます。それらの依存関係の。したがって、依存関係は、ユニットテストを書きたいクライアントクラスの新しいオペレーターに単純にインスタンス化することはできません。

最終的に、従来のモッキングツールの技術的な制限は、生産コードに次の設計制限を課します。

  1. テストでock笑する必要がある各クラスは、個別のインターフェイスを実装するか、最終的にしないでください。
  2. テストする各クラスの依存関係は、構成可能なインスタンス作成方法(工場またはサービスロケーター)を介して取得するか、依存関係の注入のために露出する必要があります。それ以外の場合、ユニットテストは、テスト中のユニットに依存関係のモック実装を渡すことができません。
  3. インスタンスメソッドのみをモックすることができるため、ユニットテストを受けるクラスは、依存関係の静的メソッドを呼び出すことも、コンストラクターのいずれかを使用してインスタンス化することもできません。

上記はからコピーされます http://jmockit.org/about.html 。さらに、それはいくつかの方法でそれ自体(JMockit)、PowerMock、およびMockitoを比較します。

現在、Java用の他のモッキングツールがあります。これは、PowerMock、JeasyTest、Mockinjectの間に、従来のものの制限を克服しています。 Jmockitの機能セットに最も近いのはPowerMockなので、ここで簡単に評価します(他の2つはより限られており、積極的に開発されていないようです)。

JMockit vs PowerMock

  • まず、PowerMockはモッキング用の完全なAPIを提供するのではなく、代わりに別のツールの拡張機能として機能します。これは、これらのツールの既存のユーザーにとって明らかに利点です。
  • 一方、JMockitはまったく新しいAPIを提供しますが、その主なAPI(期待)はEasyMockとJMockの両方に似ています。これにより、より長い学習曲線が作成されますが、JMockitはAPIをよりシンプルで、より一貫性のある、使いやすくすることもできます。
  • jmockitの期待APIと比較して、PowerMock APIはより「低レベル」であり、ユーザーにテストのためにどのクラスを準備する必要があるかを特定して指定することを強制します(@PrepareFortest({classa.class、...})注釈)および生産コードに存在する可能性のあるさまざまな種類の言語構成を処理するために特定のAPI呼び出しを必要とする:静的方法(classa.class))、コンストラクター(suppless(constructor(classxyz.class))、コンストラクターの招待状( expectnew(aclass.class))、partial mocks(createpartialmock(classx.class、 "methodtomock"))など。
  • jmockitの期待により、あらゆる種類の方法とコンストラクターは、 @mockedアノテーションの正規表現を通じて、または単に記録された期待のないメンバーを「モック解除」することによって、部分的なモッキングが純粋に宣言的な方法でock笑されます。つまり、開発者は、テストクラスの共有「モックフィールド」、または個々のテスト方法の「ローカルモックフィールド」および/または「モックパラメーター」を単純に宣言します(そして、この最後のケースでは、@Mocked Annotationはしばしばしません必要とされる)。
  • Jmockitで利用可能ないくつかの機能は、モッキングのサポートとハッシュコード、オーバーライドされた方法など、PowerMockではサポートされていません。また、テストコード自体が実際の実装クラスの知識を持たずに、テストの実行時に指定されたベースタイプのインスタンスをキャプチャしてモックするjmockitの能力に相当するものはありません。
  • PowerMockは、モックされたクラスの変更されたバージョンを生成するために、カスタムクラスローダー(通常はテストクラスごとに1つ)を使用します。このようなカスタムクラスローダーを大量に使用すると、サードパーティライブラリとの競合につながる可能性があるため、テストクラスで@powerMockignore( "package.to.be.ignored")注釈を使用する必要があります。
  • JMockit(「Javaエージェント」を介したランタイムインストルメントレーション)が使用するメカニズムは、JDK 1.5で開発する際に「-javaagent」パラメーターをJVMに渡す必要がありますが、よりシンプルで安全です。 JMOCKITは、ADTACH APIを使用してJavaエージェントをオンデマンドで透過的にロードできるため、JDK 1.6+(古いバージョンに展開しても、開発には常に使用できます)では、そのような要件はありません。

別の最近のモッキングツールはモキトです。古いツール(Jmock、EasyMock)の制限を克服しようとはしていませんが、模擬の新しいスタイルの動作テストを導入します。 Jmockitは、Verifications APIを通じて、この代替スタイルもサポートしています。

JMockit vs Mockito

  • Mockitoは、レコード((...))を区別し、フェーズを確認する((...))フェーズを確認するために、APIへの明示的な呼び出しに依存しています。これは、テストコードで模擬オブジェクトへの呼び出しがモッキングAPIへの呼び出しが必要であることを意味します。さらに、これはしばしば(...)(mock)...呼び出しを検証するときに繰り返しにつながります。
  • JMockitでは、同様の呼び出しが存在しません。確かに、新しいnontsctexpectations()とnew verifications()constructorコールがありますが、テストごとに1回しか発生し(通常)、モックされたメソッドとコンストラクターへの呼び出しとは完全に分離されています。
  • Mockito APIには、モックされたメソッドへの呼び出しに使用される構文のいくつかの矛盾が含まれています。レコードフェーズでは、when(mock.mockedmethod(args))のような呼び出しがあります。最初のケースでは、mockedMethodへの呼び出しがモックオブジェクトに直接作成され、2番目のケースでは、検証(MOCK)によって返されるオブジェクトで作成されます。
  • Jmockitには、mockedされた方法への招待は常にモックされたインスタンス自体に直接行われるため、そのような矛盾はありません。 (1つの例外を除き、同じモックされたインスタンスでの呼び出しを一致させるには、Oninstance(MOCK)コールが使用され、OnInstance(MOCK).MockedMethod(ARGS)のようなコードが使用されます。ほとんどのテストはこれを使用する必要はありません。 ))
  • メソッドチェーン/ラッピングに依存する他のモッキングツールと同様に、モッキートは、ボイドメソッドをスタブするときに一貫性のない構文にも遭遇します。たとえば、(mockedlist.get(1))。thenthrow(new runtimeexception());非voidメソッドの場合、およびdothrow(new runtimeexception())。when(mockedlist).clear();ボイドの場合。 jmockitでは、常に同じ構文です:mockedlist.clear(); result = new runtimeexception();。
  • さらに別の矛盾は、モッキートスパイの使用で発生します。「モック」は、実際の方法をSPIEDインスタンスで実行できるようにします。たとえば、Spyが空のリストを指す場合、when(spy.get(0))。thenreturn( "foo")を書く代わりに、doreturn( "foo")を書き込む必要があります。 0)。 JMockitを使用すると、動的なモッキング機能はスパイと同様の機能を提供しますが、リプレイフェーズでのみ実際の方法が実行されるため、この問題はありません。
  • Javaの最初のモッキングAPIであるEasyMockとJmockでは、(デフォルトでは)予期しない招待状を許可しないモックオブジェクトのために、モックされたメソッドの予想される呼び出しの記録に完全に焦点が当てられていました。これらのAPIは、予期しない呼び出しを可能にする模擬オブジェクトの許可された呼び出しの録音も提供しますが、これはセカンドクラスの機能として扱われました。さらに、これらのツールを使用すると、テスト中のコードが実行された後、模擬への呼び出しを明示的に検証する方法はありません。そのようなすべての検証は、暗黙的かつ自動的に実行されます。
  • モッキート(およびユニタイルモック)では、反対の視点が取られます。記録されているかどうかにかかわらず、テスト中に発生する可能性のあるオブジェクトを模倣するすべての呼び出しは許可されていません。検証は、テスト中のコードが実行された後、自動的に行われた後に明示的に実行されます。
  • どちらのアプローチも極端すぎるため、最適ではありません。 Jmockitの期待と検証は、開発者が各テストのStrict(デフォルトで期待される)と非厳格(デフォルトで許可)のmockの呼び出しの最適な組み合わせをシームレスに選択できるようにする唯一のAPIです。
  • より明確にするために、Mockito APIには次の欠点があります。テスト中にボイド非模型のメソッドへの呼び出しが発生したが、テストでは、リターンタイプのデフォルトとは異なるその方法からの返品値が必要であることを確認する必要がある場合、Mockitoテストには複製コードがあります。 a(mock.somemethod())。sonreturn(xyz)レコードフェーズを呼び出し、検証フェーズでbefify(mock).somemethod()を呼び出します。 JMockitを使用すると、厳密な期待を常に記録できます。これは明示的に検証する必要はありません。あるいは、記録された非厳格な期待に対して呼び出しカウント制約(時間= 1)を指定することができます(模範を使用すると、そのような制約は検証(mock、制約)呼び出しでのみ指定できます)。
  • Mockitoには、検証の順番と完全な検証のための構文が不十分です(つまり、オブジェクトをmockするすべての呼び出しが明示的に検証されていることを確認します)。最初のケースでは、追加のオブジェクトを作成する必要があり、その上に作成されたことを確認する必要があります:inorder inorder = inorder(mock1、mock2、...)。 2番目のケースでは、VerifyNomoreInteractions(MOCK)またはVerifyZeroInteractions(MOCK1、MOCK2)などの呼び出しを行う必要があります。
  • jmockitを使用すると、新しいverificationsinorder()またはnew Fullverifications()を新しいverifications()(またはnew fullverificationinorder()を作成して両方の要件を組み合わせるだけです。どのモックオブジェクトが関係しているかを指定する必要はありません。余分なモッキングAPI呼び出しはありません。また、ボーナスとして、順序付けられた検証ブロック内でUnverifiedInvocation()を呼び出すことにより、モッキートでは単に不可能な注文関連の検証を実行できます。

最後に、jmockitテストツールキットにはaがあります より広いスコープより野心的な目標 完全で洗練された開発者テストソリューションを提供するために、他のモッキングツールキットよりも。人工的な制限がなくても、モッキングに適したAPIは、テストを生産的に作成するのに十分ではありません。 IDEに依存しない、使いやすく、統合されたコードカバレッジツールも不可欠であり、JMockitカバレッジが提供することを目指しています。テストスイートのサイズが大きくなるにつれてより有用になる開発者テストツールセットのもう1つの部分は、生産コードをローカライズされた変更後にテストを徐々に再実行する機能です。これはカバレッジツールにも含まれています。

(確かに、ソースは偏っているかもしれませんが、まあ...)

一緒に行くと思います jmockit. 。使用するのが最も簡単で、柔軟性があり、テストするクラスを制御できない場合は、ほとんどすべてのケースや困難なケースやシナリオでも機能します(または、互換性の理由などのために壊れることはできません)。

JMockitでの私の経験は非常に前向きでした。

他のヒント

私はモッキートとjmockitの両方で仕事をしましたが、彼らとの私の経験は次のとおりです。

  • モキト:

    • 暗黙のモッキング( - >より良い使いやすさですが、モックで許可されていないメソッド呼び出しを検出できない危険があります)
    • 明示的な検証
  • EasyMock:

    • モッキングを説明します
    • 暗黙の検証
  • jmockit:

    • 両方をサポートします
  • その上、JMockitの他の利点:

    • 静的メソッド/コンストラクターなど(UTなしで非常に古いレガシーコードベースを拡張するなど)をock笑する場合、2つの選択肢があります。
    • 組み込みカバレッジレポート

私は個人的にはJMockitを好みますが、これはより豊富で柔軟な機能だと思いますが、少し急な学習曲線が必要です。通常、同じモッキング効果を達成するには複数の方法があり、モックを設計する際にはより多くの注意が必要です。

jmockitを使用します それだけ deencapsultation.classの反射ライブラリのためです。私は実際にモッキートのスタイルが大好きですが、コードを変更してAPIを泥だらけにすることを拒否しているので、限られたテストフレームワークがそれを得ることができます。そして、私はすべてのコードをテストするのがファンなので、プライベートな方法を簡単にテストできないフレームワークは、私が使用したいものではありません。

私は揺れました この記事

(明らかに大きな)学習曲線の後、JMockitは現在、模擬の私の主要なテストフレームワークになりました。

レガシーコードベース(多くの静的メソッド呼び出しなど)を簡単にテストするために、JMockitは非常に貴重です。 [恥ずかしがり屋のプラグ 記事 私のブログで

私は個人的に好む EasyMock.
素敵な、通常の、厳格なモッキングコントロールを迂回する機能は、私のお気に入りの機能のものです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top