290

ここで静的メソッドに関するいくつかのスレッドを読みましたが、静的メソッドの誤用/過度の使用が引き起こす可能性のある問題を理解していると思います。しかし、なぜ静的メソッドをモックするのが難しいのか、その真相はわかりませんでした。

PowerMock などの他のモッキング フレームワークでそれができることは知っていますが、なぜ Mockito でできないのでしょうか?

この記事を読んだのですが、著者は宗教的にこの言葉staticに反対しているようで、私の理解不足なのかもしれません。

簡単な説明/リンクは素晴らしいでしょう。

4

7 に答える 7

250

その理由は、モック オブジェクト ライブラリが通常、実行時にクラスを動的に作成することによって ( cglibを使用して) モックを作成するためだと思います。これは、実行時にインターフェイスを実装するか (私が間違っていなければ EasyMock が行うことです)、クラスから継承してモック化するか (私が間違っていなければ Mockito が行うことです) のいずれかを意味します。継承を使用してそれらをオーバーライドできないため、両方のアプローチは静的メンバーには機能しません。

静的をモックする唯一の方法は、実行時にクラスのバイト コードを変更することです。これは、継承よりも少し複雑だと思います。

それは私の推測です、それが価値があるのは...

于 2010-12-19T09:43:31.813 に答える
25

静的メソッドをモックする必要がある場合、それは設計が悪いことを示す強力な指標です。通常、テスト対象のクラスの依存関係をモックします。テスト対象のクラスが静的メソッド (たとえば java.util.Math#sin など) を参照している場合は、テスト対象のクラスが正確にこの実装を必要とすることを意味します (たとえば、精度と速度)。具体的な sinus 実装から抽象化したい場合は、おそらくインターフェイスが必要です (これがどこに行くのかがわかります)?

于 2010-12-19T18:04:39.630 に答える
2

静的メソッドもモックする必要がある場合、それはコードの匂いだと真剣に考えています。

  • 一般的な機能にアクセスするための静的メソッド? -> シングルトン インスタンスを使用し、それを注入します
  • サードパーティのコード? -> 独自のインターフェイス/デリゲートにラップします (必要に応じてシングルトンにもします)

これがやり過ぎに思えるのは Guava のようなライブラリだけですが、ロジックの一部であるため、とにかくこの種をモックする必要はありません... (Iterables.transform(..) のようなもの)
そうすれば、あなた自身のコードクリーンなままで、すべての依存関係をクリーンな方法でモックアウトでき、外部依存関係に対する破損防止レイヤーがあります。実際に PowerMock を見たことがありますが、PowerMock が必要なすべてのクラスの設計が不十分でした。また、PowerMock の統合によって深刻な問題が発生することがありました
(例: https://code.google.com/p/powermock/issues/detail?id=355 ) 。

PS: プライベート メソッドについても同様です。テストがプライベート メソッドの詳細を知る必要はないと思います。クラスが非常に複雑で、プライベート メソッドをモックアウトしたくなる場合は、おそらくそのクラスを分割する兆候です...

于 2014-07-20T23:08:07.500 に答える
0

場合によっては、特にモックする必要がある場合、静的メソッドのテストが難しいことがあります。これが、ほとんどのモック フレームワークが静的メソッドをサポートしていない理由です。このブログ投稿は、静的メソッドとクラスをモックする方法を決定するのに非常に役立つことがわかりました。

于 2010-12-19T09:35:43.477 に答える