12

単体テストに関しては、本番コードにテスト関連のコードを含めるべきではないと教えられました。

さて、単体テストを試みるたびに、そのルールを破っているような気がします。

アセンブリの内部にクラスがありXyzzyます。それを別のクラスに依存性注入してからスタブ化して、他のクラスを分離してテストできるようにしたいので、インターフェイスを作成しますIXyzzy。おっと、今私は実際にテストのためだけにあるコードを本番環境に持っています。さらに悪いことに、私はインターフェースとは何かに反対しました(それ何であるかではなく、実装者がができるかを説明します)。XyzzyのパブリックインターフェイスとIXyzzyはまったく同じであり、他の誰も(スタブを除いて)IXyzzyを実装していません。

それは私には悪いことのように思えます。

Overridable抽象基本クラスを作成したり、Xyzzy /でテストしたいすべてのパブリックメソッドを作成したりできますvirtualが、Xyzzyは継承用に設計されておらず、YAGNIの観点からは継承されないため、これも間違っています。

アンチパターンをテストすることのみを目的として、単一の実装者インターフェイスを作成していますか?より良い選択肢はありますか?

4

3 に答える 3

6

テスト専用のコードを用意するのは間違いではありません。これは実際には正常です。本番コードにデバッグと本番監視のためだけに作成された機能が含まれているのと同じです。これを禁止すべき明確な理由はありません。コードは、アプリケーションのライフサイクルのすべての側面をサポートする必要があります。テストはライフサイクルの別の部分にすぎません。

その意味で、インターフェースを使用したアプローチは正しいです。本番アプリケーションの残りの部分もインターフェイスを使用するようにすると(1つしかないのに具体的なクラスではなく)、アーキテクチャ的には健全です。

私はインターフェースとは何かに反対しました(それが何であるかではなく、実装者が何ができるかを説明します)

インターフェイスはオブジェクトが実行できることを記述しているため、ここではあなたの主張を理解できませんでした。具体的な(本番)実装が1つしかない場合でも、このプロパティは破壊されません。

考えてみれば、すべてのクラスには、より緩い意味での「インターフェイス」があります。すべてのメソッドのパブリックシグネチャは、クラスがサポートするインターフェイスを外部に公開します。.NETインターフェースが実装されているかどうかは、単なる詳細です。クラスはまだ外部に同じ約束をします。

于 2013-02-20T23:59:04.000 に答える
4

私の経験では、これは.NET開発の非常に典型的なものであり、メソッドのオーバーライドがオプトインベースであるという事実に起因しています。依存関係をモックしたい場合は、メソッドがすべて仮想であるインターフェースまたはオブジェクトのいずれかが必要です。

すべてのメソッドがオーバーライド可能なJavaのような言語では、単一実装のインターフェースは確かにアンチパターンであり、優れた開発者はそれを呼び出すでしょう。

あなたがしていることを続けてください-あなたが犯しているどんな罪も、私の見解では、あなたのユニットテストの利点によって手軽に上回っています!

于 2013-02-21T01:20:47.770 に答える
3

はい、それはアンチパターンです。パターンは、「特定のコンテキストでの一般的な問題の解決策」になります。しかし、この場合、私たちが持っているのは回避策であり、解決策ではありません。

問題の問題は、テスト対象のユニットをその依存関係(の一部)から分離する必要があるため、ユニットテストを作成するときにこれらの依存関係の実装を考慮する必要がないことです。この問題の一般的で真の解決策は「モック」と呼ばれ、テスト作成者はモックされた依存関係から必要な動作を指定できます。

対照的に、開発者に不要な個別のインターフェイスを作成するように強制したり、メソッドをとして宣言したりすることvirtualは、ユニットを他のユニットからきれいに分離することが技術的に不可能な場合の回避策にすぎません。

.NETの場合、この分離機能を提供するいくつかのモックツール、つまりTypeMock Isolator、JustMock、およびMSFakesがあります。他の言語/プラットフォーム(Java、Ruby、Pythonなど)には、同様の表現力を持つ独自のツールがあります。

于 2013-02-22T12:22:01.767 に答える