モックフレームワークを探していないと仮定すると、それらは超ユビキタスで見つけやすいので、事前に注目する価値のあるものがいくつかあります。
- 「常に」行うべき「何か」はありません。
サードパーティのライブラリをまとめるのが常に最善とは限りません。アプリケーションが本質的にライブラリに依存している場合、または1つまたは2つのコアライブラリを中心に構築されている場合は、時間を無駄にしないでください。ライブラリが変更された場合、アプリケーションを変更する必要があります。
- 統合テストを使用してもかまいません。
これは、安定しているか、アプリケーションに固有であるか、簡単にモックできない境界の周辺で特に当てはまります。これらの条件が満たされている場合、ラッピングとモックは複雑で退屈です。その場合、私は両方を避けます:ラップしないでください、モックしないでください。統合テストを書くだけです。(自動テストが目標の場合。)
- ツールとフレームワークでは、論理的な複雑さを排除できません。
原則として、ツールは定型文のみを削減できます。しかし、複雑なインターフェイスを取得してそれを単純にする自動化可能なアルゴリズムはありません。もちろん、インターフェイスXを取得して、ニーズに合わせて調整することはできません。(このアルゴリズムを知っているのはあなただけです!)ですから、シンラッパーを生成できるツールは間違いなくありますが、最終的にはインテリジェントに、したがって手動でコーディングする必要があるため、それらはまだユビキタスではないことをお勧めしますラッパーの後ろに隠れていても、インターフェースに対して。
ただし、クラスを直接参照することを避けるために、多くの言語で使用できる戦術があります。また、場合によっては、実際には存在しないインターフェイスまたは薄いラッパーを「偽装」することもできます。たとえば、C#では、次の2つのルートのいずれかを使用します。
- ファクトリーと暗黙的なタイピングを使用します。
この小さなコンボで複雑なクラスを完全にラップする手間を回避できます。
// "factory"
class PdfDocumentFactory {
public static ExternalPDFLibraryDocument Build() {
return new ExternalPDFLibraryDocument();
}
}
// code that uses the factory.
class CoreBusinessEntity {
public void DoImportantThings() {
var doc = PdfDocumentFactory.Build();
// ... i have no idea what your lib does, so, I'm making stuff but.
// but, you can do whatever you want here without explicitly
// referring to the library's actual types.
doc.addHeader("Wee");
doc.getAllText().makeBiggerBy(4).makeBold().makeItalic();
return doc.exportBinaryStreamOrSomething();
}
}
あなたはより多くの「機能的」アプローチを通じてまたは辞書(またはそれらを格納することにより、いずれか、メンバーとしてこれらのオブジェクトを保存しないようにすることができた場合は何でも)、このアプローチは、あなたのコアビジネスエンティティが知らなくても、コンパイル時の型チェックの利点があり、正確に作業しているクラス。
必要なのは、コンパイル時に、ファクトリによって返されるクラスに、ビジネスオブジェクトが使用しているメソッドが実際に含まれていることだけです。
- 動的型付けを使用します。
これは暗黙的な型指定を使用するのと同じ流れですが、別のトレードオフが伴います。コンパイル型チェックを失い、外部依存関係をクラスメンバーとして匿名で追加し、依存関係を注入することができます。
class CoreBusinessEntity {
dynamic Doc;
public void InjectDoc(dynamic Doc) {
Doc = doc;
}
public void DoImortantThings() {
Doc.addHeader("Wee");
Doc.getAllText().makeBiggerBy(4).makeBold().makeItalic();
return Doc.exportBinaryStreamOrSomething();
}
}
これらの両方の戦術では、モックするときが来るExternalPDFLibraryDocument
と、前に述べたように、やるべきことがいくつかありますが、とにかくやらなければならない仕事です。そして、この構造により、何百もの細い小さなラッパークラスを退屈に定義することを避けました。ほとんどの場合、ライブラリを直接見ることなくライブラリを使用しただけです。
以上のことから、サードパーティのライブラリを明示的にまとめることを検討する3つの大きな理由がありますが、いずれもツールやフレームワークの使用を示唆するものではありません。
- 特定のライブラリは、アプリケーションに固有のものではありません。
- ラップせずにスワップするのは非常に高価です。
- API自体は好きではありません。
私はそれらの領域のすべての3つの内のいくつかのレベルの懸念を持っていない場合、あなたはしていない任意の作る重要なそれを包むための努力を。また、3つの領域すべてに何らかの懸念がある場合、自動生成されたシンラッパーは実際には役立ちません。
ライブラリをラップすることにした場合、時間を最も効率的かつ効果的に使用するのは、必要なインターフェイスに対してアプリケーションを構築することです。既存のAPIに対してではありません。
別の言い方をすれば、古典的なアドバイスに注意してください。可能な限りの決定をすべて延期します。最初にアプリケーションの「コア」をビルドします。最終的に希望することを実行するインターフェースに対するコード。これは、最終的にはまだ存在しない「周辺機器」によって実現されます。必要に応じてギャップを埋めます。
この努力はないかもしれないと感じた時間、保存されたように、しかし、ラッパーが必要だと思う場合、これは安全にそれを行う最も効率的な方法です。
このように考えてください。
たとえコードがラップされていても、コードの暗いコーナーでこのライブラリに対してコードを作成する必要があります。テスト中にライブラリをモックすると、たとえそれがラップアップされていても、避けられない手作業がそこにあります。しかし、それは、アプリケーションの大部分でそのライブラリを名前で直接確認する必要があるという意味ではありません。
TLDR
ライブラリをラッピングする価値がある場合は、戦術を使用して、サードパーティライブラリへの広範な直接参照を回避しますが、シンラッパーを生成するためのショートカットを使用しないでください。最初にビジネスロジックを構築し、インターフェイスについて慎重に検討し、必要に応じてアダプタを有機的に出現させます。
そして、それに関しては、統合テストを恐れないでください。それらは少しファジーですが、それでも動作コードの証拠を提供し、回帰を寄せ付けないように簡単に作成できます。