たくさんのリソースがありますが、ここSOでも、これらのQ/Aで比較される用語は2つだけです。
それで、要するに、それらのそれぞれは何ですか?そして、それらはすべて互いにどのように関係していますか?それとも、まったくそうではありませんか?
たくさんのリソースがありますが、ここSOでも、これらのQ/Aで比較される用語は2つだけです。
それで、要するに、それらのそれぞれは何ですか?そして、それらはすべて互いにどのように関係していますか?それとも、まったくそうではありませんか?
モックとスタブの違いは非常に単純です。モックはテストを失敗させる可能性がありますが、スタブは失敗する可能性があります。これですべてです。さらに、スタブは値を提供するものと考えることができます。今日では、偽物は両方の総称です(これについては後で詳しく説明します)。
通信プロトコルを介してパッケージを送信するサービスを構築する必要がある場合を考えてみましょう(正確な詳細は関係ありません)。パッケージコードを使用してサービスを提供するだけで、後はそれが実行されます。以下のスニペットを前提として、どの依存関係がスタブになり、どの単体テストのモックになるかを特定できますか?
public class DistributionService
{
public double SendPackage(string packageCode)
{
var contents = this.packageService.GetPackageContents(packageCode);
if (contents == null)
{
throw new InvalidOperationException(
"Attempt to send non-exisiting package");
}
var package = this.packageBuilder.Build(contents);
this.packageDistributor.Send(package);
}
}
それはpackageBuilder
単に価値を提供するだけであり、テストを失敗させる可能性のある方法はありません。それはスタブです。ぼやけているように見えるかもしれませんが、packageService
スタブでもあります。これは値を提供します(値を使用して行うことは、スタブの観点からは無関係です)。もちろん、後でその値を使用して例外がスローされるかどうかをテストしますが、それでもすべて制御範囲内にあります(たとえば、スタブに何をすべきかを正確に指示し、それを忘れます-テストにそれ以上の影響はないはずです)。
とは異なりpackageDistributor
ます。たとえそれが何らかの価値を提供したとしても、それは消費されません。それでも、への呼び出しは実装の非常に重要な部分のようであり、呼び出されていることを確認Send
したいと思うでしょう。
この時点でpackageDistributor
、モックである結論に到達する必要があります。メソッドが呼び出されたことを表明する専用の単体テストがありますが、Send
何らかの理由で呼び出されなかった場合は、プロセス全体の重要な部分であるため、それを知りたいと思います。他の依存関係はスタブであり、他の、おそらくより関連性の高いコードに値を提供するだけです。
スタブはスタブであり、単純な実装では定数値に置き換えることもできます。
var contents = "Important package";
var package = "<package>Important package</package>";
this.packageDistributor.Send(package);
これは基本的に、モックフレームワークがスタブで行うことです-構成可能/明示的な値を返すようにスタブに指示します。昔ながらの手巻きのスタブは、多くの場合、まさにそれを実行します-定数値を返します。
明らかに、そのようなコードはあまり意味がありませんが、TDDを実行したことがある人なら誰でも、クラス開発の初期段階でそのような単純な実装をたくさん見たことは確かです。TDDから生じる反復型開発は、多くの場合、クラスの依存関係の役割を特定するのに役立ちます。
この投稿の冒頭で、偽物は単なる一般的な用語であると述べました。モックはスタブとしても機能する可能性があることを考えると(特に最新のモックフレームワークが関係している場合)、混乱を避けるために、そのようなオブジェクトを偽物と呼ぶことをお勧めします。今日、この傾向が高まっているのを見ることができます-元のモック-スタブの区別は徐々に過去のものになりつつあり、より普遍的な名前が使用されています。例えば:
モックとスタブはどちらもフェイクオブジェクトと呼ばれます。私の意見では:
スタブは外部依存関係を置き換えるために使用され、例外なくテストを実行します。テストが失敗したかどうかを判断するには、Assertを使用する必要があります。スタブは、一部の関数の結果が正しいかどうかをテストする場合にのみ適しています
モックはより複雑で、動作をテストするためによく使用されます。たとえば、検証が呼び出された関数であるかどうか
それらは一般的に交換可能ですが、私の意見にはわずかな違いがあります。