1

new一部のコードをリファクタリングしているときに、具象クラスを作成する呼び出しがあることがわかりました。

具体的なクラスを作成するための呼び出しを回避し、テスト容易性を向上させる方法を探していたので、インスタンスを返す役割を担う一種の Factory を作成しました。次に、Spring コンストラクター注入を使用して、ファクトリをテスト対象のシステムに注入します。

ただし、現在、ファクトリのメソッドを静的にすると同時に、テスト容易性を高めることについての質問に直面しています。Misko Hevery によると、静的メソッドはテスト容易性にとって致命的ですが、new の呼び出しを削除し、適切な単体テストを行い、静的メソッドの呼び出しを回避するために何をすべきか明確な考えがありません。

これは、ファクトリを使用するクラスからの抜粋です。構築された (およびモックされた) columnFamilyTemplate を使用するこのクラスのメソッドをテストしています。

protected AlertFieldMatcher(ColumnFamilyTemplateBuilder columnFamilyTemplateBuilder, Keyspace keyspace,
                            T2JsonUtilInterface jsonUtil) {
    this.columnFamilyTemplate = columnFamilyTemplateBuilder.build(keyspace, CF_ALERT);
    this.jsonUtil = jsonUtil;
}



これがファクトリで、SUT (上記) のメソッドのテストでモックする必要があります。

public class DefaultColumnFamilyTemplateBuilder 
                                         implements ColumnFamilyTemplateBuilder {


   @Override
   public ColumnFamilyTemplate<String, String> build(Keyspace keyspace, 
                                                       String columnFamily) {
       ColumnFamilyTemplate<String, String> builtTemplate = 
                                                 new ThriftColumnFamilyTemplate<String, String>
                                                    (keyspace, 
                                                      columnFamily,
                                                      StringSerializer.get(), 
                                                      StringSerializer.get());
       return builtTemplate;
   }

   ...
}

私が見る唯一のオプションは、Factory タイプのオブジェクトをそのままにしておくことです。つまり、メソッドを静的にしないことです。

4

2 に答える 2

1

アプリケーションから「new」を削除する場合は、代わりにオブジェクトを作成するメカニズムが必要です。確認したいメカニズムが 3 つあります。

1つ目は依存性注入です。DI コンテナーを使用すると、よりインターフェイスベースのアプローチを採用し、実行時に使用する実装を選択できます。Spring は最も人気のある DI コンテナーであり、CDI は新しい「標準」です。DI は問題ありませんが、必ずしもプロジェクトの後半に導入したい種類のものではありません。

2 番目のメカニズムは Java ServiceLoader で、クラスパスにファイルを追加および削除することでコンポーネントの実装を変更できます。これは少し面倒に感じるかもしれません。

最後のメカニズムは、ファクトリ オブジェクトのクラス名であるプロパティを読み込む静的メソッド (!!!!) を使用し、Class.forName().newInstance() を使用してファクトリ オブジェクトを作成することです。これが最も簡単な方法かもしれません。これにより、新しいモック ファクトリを挿入するための継ぎ目が提供されます。

静的を回避することは良い考えですが、静的には場所があります。関連するトレードオフを理解している場合は、それらを使用してください。

于 2013-10-28T16:59:20.013 に答える
1

明示的にファクトリーを作成する必要はありません。

新しいインスタンスの作成をクラスの保護されたメソッドに抽出します。これは、ファクトリ メソッドnew ThriftColumnFamilyTemplate(...)を作成するがデフォルトの実装として提供する場合とまったく同じです。

単体テストでは、sut は、実際のクラスではなく、ファクトリ メソッドをモックするクラスの部分的にモックされたバージョンになります。このアプローチでは、テストされていない唯一のコードはファクトリ メソッド、つまり 1 行です。部分的なモッキングには、EasyMock IMockBuilderを使用できます。

于 2013-11-05T13:08:27.297 に答える