モックはオープン/クローズの原則に違反しますか?


13

少し前に、私は見つけることができないStack Overflowの回答で、パブリックAPIをテストする必要があることを説明した文を読み、著者はインターフェイスをテストする必要があると言いました。また、メソッドの実装が変更された場合、テストケースを変更する必要はありません。これを行うと、テスト中のシステムが機能することを確認する契約が破られるため、著者は説明しました。つまり、メソッドが機能しない場合はテストが失敗しますが、実装が変更されたためではありません。

私たちがock笑について話すとき、これは私の注意を呼びました。モックはテスト対象システムの依存関係からの期待呼び出しに大きく依存しているため、モックはインターフェイスではなく実装と密接に結合されています。

モックとスタブの調査中、いくつかの記事は、依存関係からの期待に依存しないため、モックの代わりにスタブを使用する必要があることに同意しています。

私の質問は次のとおりです。

  1. モックはオープン/クローズの原則に違反しますか?
  2. 最後の段落のスタブを支持する議論に欠けているものはありますか?
  3. もしそうなら、いつスモックを作成するのに適したユースケースになり、スタブを使用するのに適したユースケースになりますか?


8
Since mocking relays heavily on expectation calls from system under test's dependencies...これがあなたがおかしくなるところだと思います。モックは、外部システムの人工的な表現です。 外部システムに依存するコードに対してテストを実行できるように外部システムをシミュレートする場合を除いて、外部システムを決して表しません。コードが実際のモックのないシステムで
ロバートハーヴェイ

8
別の言い方をすれば、モックは代替実装です。 そもそも、実際の実装の代用としてモックを使用できるように、最初にインターフェイスにプログラミングした理由です。つまり、モックは実際の実装から切り離されており、実際の実装から切り離されています。
ロバートハーヴェイ

3
「言い換えると、メソッドが機能しない場合、テストは失敗するはずですが、実装が変更されたためではありません」、これは必ずしも当てはまりません。実装とテストの両方を変更する必要がある状況はたくさんあります。
-whatsisname

回答:


4
  1. モックがなぜオープン/クローズド原則に違反するのかわかりません。なぜそう思うかを説明していただければ、懸念を軽減できるかもしれません。

  2. 私が考えることができるスタブの唯一の欠点は、それぞれが実際に依存インターフェースの代替実装であるため、一般にモックよりも多くの作業を必要とすることです。したがって、一般に完全な(または説得力のある完全な)依存インターフェースの実装。極端な例を挙げると、テスト対象のサブシステムがRDBMSを呼び出す場合、RDBMSのモックは、テスト対象のサブシステムによって発行されることがわかっている特定のクエリに単に応答し、テストデータの所定のセットを生成します。一方、代替の実装は本格的なインメモリRDBMSであり、おそらく実稼働で使用している実際のクライアントサーバーRDBMSの癖をエミュレートしなければならないという余分な負担を伴います。(幸運なことに、HSQLDBのようなものがあるので、実際にそうすることができますが、それでも、

  3. モックの適切な使用例は、依存インターフェースが複雑すぎて代替実装を記述できない場合、またはモックを一度だけ記述し、再度触れないことが確実な場合です。これらの場合は、先に進み、すばやく汚れたモックを使用してください。したがって、スタブ(代替実装)の適切なユースケースは、他のほとんどすべてです。特に、テスト対象のサブシステムとの長期的な関係を予定している場合は、きれいできれいな代替実装を必ず行ってください。インターフェイスが変更されるたびにメンテナンスが必要になるのではなく、インターフェイスが変更された場合にのみメンテナンスが必要になります変更いつでもテスト変化の下でサブシステムの実装。

PSは、あなたが参照している人には、例えば、ここにprogrammers.stackexchange.com上の私の他のテストに関連した答えの一つに、私をされている可能性が、この1


an alternative implementation would be a full-blown in-memory RDBMS-必ずしもスタブを使用する必要はありません。
ロバートハーベイ

@RobertHarveyは、HSQLDBとH2を使用して、実際にそこまで行くことはそれほど難しくありません。そこまで行かないために、中途半端なことをするのはおそらくもっと難しいでしょう。ただし、自分でそれを行う場合は、SQLパーサーを作成することから始める必要があります。確かに、いくつかのコーナーをカットできますが、多くの作業があります。とにかく、前述したように、これは単なる極端な例です。
マイクナキス

9
  1. Open / Closedの原則は、ほとんどの場合、クラスを変更せずにクラスの動作を変更できることです。したがって、テスト対象のクラス内に模擬コンポーネントの依存関係を注入しても、それに違反することはありません。

  2. テストダブル(モック/スタブ)の問題は、テスト対象のクラスがその環境とどのように相互作用するかに関して基本的に任意の仮定を行うことです。これらの期待が間違っている場合、コードをデプロイすると問題が発生する可能性があります。余裕がある場合は、実稼働環境の境界と同じ制約内でコードをテストしてください。できない場合は、可能な限り最小限の仮定を行い、システムの周辺機器(データベース、認証サービス、HTTPクライアントなど)のみをモック/スタブします。

ダブルであるIMHOを使用する必要がある唯一の正当な理由は、テスト中のクラスとの相互作用を記録する必要がある場合、または偽のデータを提供する必要がある場合です(両方の手法で可能)。ただし、これを悪用することは、設計が悪いこと、またはテスト実装中のAPIに依存しすぎるテストを反映していることに注意してください。


6

注:このスタックに従って、「実装なしのクラス、監視できるもの」を意味するようにモックを定義し、「部分的なモック、実装されたクラスの実際の動作の一部を使用する」スタブを定義していると仮定していますオーバーフロー質問

コンセンサスがスタブを使用することだと思う理由がわかりません。たとえばMockitoのドキュメントではまったく逆です。

いつものように、部分的なモック警告を読みます:オブジェクト指向プログラミングは、複雑さを個別の特定のSRPyオブジェクトに分割することにより、複雑さへの取り組みが少なくなります。部分モックはこのパラダイムにどのように適合しますか?そうではありません...部分的なモックは、通常、複雑さが同じオブジェクトの別のメソッドに移動したことを意味します。ほとんどの場合、これはアプリケーションの設計方法ではありません。

ただし、部分モックが便利な場合はまれです:簡単に変更できないコードを扱う(サードパーティのインターフェイス、レガシーコードの暫定的なリファクタリングなど)ただし、新しいテスト駆動型のウェルモックには部分モックを使用しません。設計されたコード。

そのドキュメンテーションは、私ができるよりも良いと言っています。モックを使用すると、特定の1つのクラスだけをテストでき、それ以外は何もできません。探している動作を実現するために部分的なモックが必要な場合は、おそらく何か間違ったことをしている、SRPに違反しているなど、コードはリファクタリングに耐えることができます。モックは、とにかくテストでのみ使用されるため、そのコードに対する実際の変更ではないため、オープンクローズの原則に違反しませ。通常は、とにかくcglibのようなライブラリによってオンザフライで生成されます。


2
同じ提供されたSO質問(受け入れられた答え)から、これは私が参照していたモック/スタブ定義です:モックオブジェクトは期待を定義するために使用されます:このシナリオでは、メソッドA()がそのようなパラメータで呼び出されることを期待します モックはそのような期待を記録して検証します。一方、スタブには異なる目的があります。期待を記録または検証するのではなく、テストシナリオを利用するために、動作、「偽物」オブジェクトの状態を「置換」することを可能にします...
クリストファーフランシスコ

2

この問題は、有効なテストのみがオープン/クローズドテストを満たすテストであるという仮定から生じる可能性があると思います。

重要なテストはインターフェースをテストすることだけであることが容易にわかります。ただし、実際には、内部の動作をテストしてそのインターフェイスをテストする方が効果的です。

たとえば、「実装は例外をスローしない」などの否定的な要件をテストすることはほぼ不可能です。ハッシュマップを使用して実装されているマップインターフェイスを検討してください。ハッシュマップは、物事を再ハッシュする必要がある場合でも(危険にさらされる可能性があります)、スローせずにマップインターフェイスに適合していることを確認する必要があります。入力のあらゆる組み合わせをテストして、インターフェイスの要件を満たしていることを確認できますが、宇宙の熱死よりも時間がかかる可能性があります。代わりに、カプセル化を少し破り、より緊密に相互作用するモックを開発し、ハッシュマップにリハッシュアルゴリズムがスローしないようにするために必要な正確なリハッシュを強制的に実行させます。

Tl / Dr:「本で」それを行うのは良いことですが、プッシュが迫り来るとき、金曜日までに上司の机に製品を置くことは、熱死までかかる本のテストスイートよりも便利です適合性を確認する宇宙。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.