22

静的メソッドをモックできないモック フレームワーク (Mockito) を使用しようとしているため、質問しています。調べてみると、かなりの数のブログ投稿で、静的メソッドはできるだけ少なくすべきだと言っているのを見つけましたが、その理由を理解するのに苦労しています。具体的には、メソッドがグローバル状態を変更せず、基本的にヘルパー メソッドである理由です。たとえば、ApiCallerいくつかの静的メソッドを持つというクラスがあります。静的メソッドの目的の 1 つは、HTTP 呼び出しを実行し、サーバーが返したカスタムの問題 (ユーザーがログインしていないなど) を処理し、応答を返すことです。単純化すると、次のようになります。

public class ApiCaller {
...
   public static String makeHttpCall(Url url) {
        // Performs logic to retrieve response and deal with custom server errors
        ...
        return response;
   }
}

これを使用するには、呼び出すだけですApiCaller.makeHttpCall(url) 。次のように、これを非静的メソッドに簡単に作成できます。

public class ApiCaller {
...
   public String makeHttpCall(Url url) {
        // Performs logic to retrieve response and deal with custom server errors
        ...
        return response;
   }
}

次に、このメソッド呼び出しを使用しますnew ApiCaller().makeHttpCall()が、これは余分なオーバーヘッドのように思えます。なぜこれが悪いのか、そしてモッキングフレームワークを使用してこれらのメソッドをスタブ化できるように、メソッドを非静的にする (キーワードを削除する以外に) より良い解決策があるかどうかを誰かが説明できますか?

ありがとう!

4

5 に答える 5

9

静的メソッドの問題は、テストしようとしているシステムに関連していない場合、それらを偽造するのが非常に難しいことです。このコードを想像してみてください。

public void systemUnderTest() {
    Log.connectToDatabaseForAuditing();
    doLogicYouWantToTest();
}

connectToDatabaseForAuditing()メソッドは静的です。書きたいテストに対してこのメ​​ソッドが何をするかは気にしません。ただし、このコードをテストするには、利用可能なデータベースが必要です。

静的でない場合、コードは次のようになります。

private Logger log; //instantiate in a setter AKA dependency injection/inversion of control

public void systemUnderTest() {
    log.connectToDatabaseForAuditing();
    doLogicYouWantToTest();
}

そして、あなたのテストは今データベースなしで書くのは簡単でしょう:

@Before
public void setUp() {
    YourClass yourClass = new YourClass();
    yourClass.setLog(new NoOpLogger());

}

//.. your tests

メソッドが静的なときにそれを行おうとしていると想像してみてください。ロガーを変更して、データベースに接続しないようにするためinTestModeにtrueに設定したという静的変数を設定する以外の方法は考えられません。setUp()

于 2013-01-17T20:19:08.870 に答える
2

モジュール性が低くなります。ApiCaller代わりに、インスタンスメソッドを使用してインターフェイスをmakeHttpCall()定義し、将来的に個別の実装を定義できるようにする必要があります。

少なくとも、元のバージョンとモックバージョンの2つのインターフェイスの実装が常にあります。

(注:静的メソッドをモックできるモックフレームワークがいくつかあります)

補遺として、これは特定のアプリケーションには当てはまらない場合がありますが、通常、静的メソッドの使用は、より大きな設計の監視を示しています。モジュール性と再利用性を考慮した設計は、アプリケーション全体で普及している必要があります。これは、現在は必要ない場合でも、将来必要になる可能性があり、事後に変更するのがはるかに難しく、はるかに時間がかかるためです。

于 2013-01-17T20:19:01.560 に答える
0

自分の質問にほとんど答える必要があるときに、それらを簡単にモックできないこと。

特に、示されているような場合: HTTP 呼び出しを行うにはコストがかかり、コードの単体テストのためにそれを行うこと意味がありません。統合テストのために保存してください。

単体テストには、HTTP 呼び出しからの既知の応答 (および応答コード) が必要です。これは、自分が制御していないネットワークを使用して他の誰かのサービスを呼び出している場合には実行できません。

于 2013-01-17T20:26:34.283 に答える