14

たくさんのリソースがありますが、ここSOでも、これらのQ/Aで比較される用語は2つだけです。

それで、要するに、それらのそれぞれは何ですか?そして、それらはすべて互いにどのように関係していますか?それとも、まったくそうではありませんか?

4

3 に答える 3

21

モックとスタブの違いは非常に単純です。モックはテストを失敗させる可能性がありますが、スタブは失敗する可能性があります。これですべてです。さらに、スタブは値を提供するものと考えることができます。今日では、偽物は両方の総称です(これについては後で詳しく説明します)。

通信プロトコルを介してパッケージを送信するサービスを構築する必要がある場合を考えてみましょう(正確な詳細は関係ありません)。パッケージコードを使用してサービスを提供するだけで、後はそれが実行されます。以下のスニペットを前提として、どの依存関係がスタブになり、どの単体テストのモックになるかを特定できますか?

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何らかの理由で呼び出されなかった場合は、プロセス全体の重要な部分であるため、それを知りたいと思います。他の依存関係はスタブであり、他の、おそらくより関連性の高いコードに値を提供するだけです。

TDDを一目で確認

スタブはスタブであり、単純な実装では定数値に置き換えることもできます。

var contents = "Important package";
var package = "<package>Important package</package>";
this.packageDistributor.Send(package);

これは基本的に、モックフレームワークがスタブで行うことです-構成可能/明示的な値を返すようにスタブに指示します。昔ながらの手巻きのスタブは、多くの場合、まさにそれを実行します-定数値を返します。

明らかに、そのようなコードはあまり意味がありませんが、TDDを実行したことがある人なら誰でも、クラス開発の初期段階でそのような単純な実装をたくさん見たことは確かです。TDDから生じる反復型開発は、多くの場合、クラスの依存関係の役割を特定するのに役立ちます。

最近のスタブ、モック、フェイク

この投稿の冒頭で、偽物は単なる一般的な用語であると述べました。モックはスタブとしても機能する可能性があることを考えると(特に最新のモックフレームワークが関係している場合)、混乱を避けるために、そのようなオブジェクトを偽物と呼ぶことをお勧めします。今日、この傾向が高まっているのを見ることができます-元のモック-スタブの区別は徐々に過去のものになりつつあり、より普遍的な名前が使用されています。例えば:

  • FakeItEasyは偽物を使用します
  • NSubstituteはsubstituteを使用します
  • Moqはモックを使用します(名前は古いですが、スタブかモックかはわかりません)

参考文献、さらに読む

  • モックはMartinFowlerによるスタブではありません-この記事はスタブ/モックの質問の下で事実上リンクされているのを見ることができます、そしてそれは理由です
  • マーク・シーマンによるテストダブルの連続体の探索-紛らわしい単体テストの用語の概要(モック、フェイク、スタブで十分だと思った場合は、*ダミー**、スパイダブルなどもあることを知っておく必要があります)
  • xunitpatterns.com-巨大なユニットテストパターンの本の裏付けウェブサイト、 xUnitテストパターン:GerardMeszarosによる
  • Art of Unit Testing by Roy Osherove-優れたユニットテスト入門書(「モックはテストを失敗させる可能性があり、スタブではない」はロイの言葉であり、私のものではありません)
于 2012-12-04T11:40:03.143 に答える
6

モックとスタブはどちらもフェイクオブジェクトと呼ばれます。私の意見では:

  • スタブは外部依存関係を置き換えるために使用され、例外なくテストを実行します。テストが失敗したかどうかを判断するには、Assertを使用する必要があります。スタブは、一部の関数の結果が正しいかどうかをテストする場合にのみ適しています

  • モックはより複雑で、動作をテストするためによく使用されます。たとえば、検証が呼び出された関数であるかどうか

于 2012-12-04T09:09:42.630 に答える
2

それらは一般的に交換可能ですが、私の意見にはわずかな違いがあります。

  • モック/フェイクオブジェクトは、リアルな外観の結果を返します。
  • スタブはデフォルトの失敗/合格値を返します。
于 2012-12-04T08:49:24.097 に答える