web-dev-qa-db-ja.com

C#ユニットテストでモックとフェイクを使用するのはいつですか?

誰かがモックとフェイクを選択する理想的なシナリオを提案するガイドラインを思い付くことができますか?つまり、エッセンシャルを手動で設定しますか?

私はこの状況にどのように取り組むかについて少し混乱しています。

50
vijaysylvester

さて、あなたはあなたが整理する必要があるいくつかのことがあります。知っておく必要のある基本的な事項が2つあります。命名法とベストプラクティスです。

まず、優れたテスターであるRoyOsheroveからの優れたビデオリソースを提供したいと思います。

Roy Osheroveによるユニットテストレビュー

彼は、いくつかのオープンソースプロジェクトに付属しているテストハーネスのレビューをいくつか行ったと言うことから始めます。あなたはここでそれらを見つけることができます: http://weblogs.asp.net/rosherove/archive/tags/TestReview/default.aspx

これらは基本的にビデオレビューであり、彼はこれらのテストハーネスを紹介し、何が良いのか、何が悪いのかを説明します。非常に役立ちます。

ロイはまた、私が理解している本がとても良いです。

命名法

このポッドキャストは非常に役立ちますhttp://www.hanselminutes.com/default.aspx?showID=187

ただし、ポッドキャストを言い換えます(Hanselminutesのイントロ音楽は恐ろしいものです)。

基本的に、分離フレームワーク(Moq、Rhino Mocks、Type Mockなど)で行うすべてのことは、偽物と呼ばれます。

fakeは、テスト中に使用されているオブジェクトであり、テストしているコードが本番コードの代わりに呼び出すことができます。偽物は、テストしようとしているコードをアプリケーションの他の部分から分離するために使用されます。

(主に)2種類の偽物があります:スタブモック

モックは、テストしているコードがそれを呼び出すことができるように配置した偽物であり、呼び出しがで行われたと主張します正しいパラメータ。以下のサンプルは、Moq分離フレームワークを使用してこれを実行します。

[TestMethod]
public void CalculateTax_ValidTaxRate_DALCallIsCorrect()
{
    //Arrange
    Mock<ITaxRateDataAccess> taxDALMock = new Mock<ITaxRateDataAccess>();
    taxDALMock.Setup(taxDAL => taxDAL.GetTaxRateForZipCode("75001"))
                  .Returns(0.08).Verifiable();

    TaxCalculator calc = new TaxCalculator(taxDALMock.Object);

    //Act
    decimal result = calc.CalculateTax("75001", 100.00);

    //Assert
    taxDALMock.VerifyAll();
}

stubは、テストしているコードが呼び出しから一貫したデータを取得することを確認するために配置することを除いて、モックとほとんど同じです。 (たとえば、コードがデータアクセス層を呼び出す場合、スタブは偽のデータを返します)が、スタブ自体に対してアサートしません。つまり、メソッドが偽のデータアクセス層を呼び出したことを確認する必要はありません。他の何かをテストしようとしています。テストしようとしているメソッドを分離して機能させるためのスタブを提供します。

スタブの例を次に示します。

[TestMethod]
public void CalculateTax_ValidTaxRate_TaxValueIsCorrect()
{    
    //Arrange
    Mock<ITaxRateDataAccess> taxDALStub = new Mock<ITaxRateDataAccess>();
    taxDALStub.Setup(taxDAL => taxDAL.GetTaxRateForZipCode("75001"))
                  .Returns(0.08);

    TaxCalculator calc = new TaxCalculator(taxDALStub.Object); 

    //Act
    decimal result = calc.CalculateTax("75001", 100.00);

    //Assert
    Assert.AreEqual(result, 8.00);
}

ここで、メソッドが別のリソースを呼び出したという事実ではなく、メソッドの出力をテストしていることに注意してください。

Moqは実際にはモックとスタブをAPIで区別しませんが(どちらもMock<T>として宣言されていることに注意してください)、ここでの使用法はタイプを決定する上で重要です。

これがあなたをまっすぐにするのに役立つことを願っています。

83
Anderson Imes

少なくとも5種類のテストダブルがあります:ダミー、スタブ、モック、スパイ、フェイク。良い概要は http://code.google.com/testing/TotT-2008-06-12.pdf にあり、それらは http://xunitpatterns.com)にも分類されています。 /Mocks,%20Fakes,%20Stubs%20and%20Dummies.html

17
Esko Luontola

The Little Mocker 、Bob Martinから、このトピックに関する非常に良い読み物です。

[...]ずっと前に、非常に賢い人々が、モックオブジェクトという用語を紹介して定義した論文を書きました。他の多くの人がそれを読んで、その用語を使い始めました。論文を読んでいない他の人々は、その用語を聞いて、より広い意味でそれを使い始めました。彼らはみことばを動詞にさえ変えました。彼らは、「そのオブジェクトをモックアウトしましょう。」または「私たちはたくさんのモックをする必要があります」と言うでしょう。

この記事では、モック、フェイク、スパイ、スタブの違いについて説明しています。

1
Benoit Blanchon

コードのチャンクをテストしたいのですが、メソッドとしましょう。このメソッドは、http urlからファイルをダウンロードし、そのファイルをディスクに保存してから、ファイルがディスク上にあることをメールで送信します。もちろん、これら3つのアクションはすべて、メソッド呼び出しのサービスクラスです。これは、モックが簡単だからです。これらをモックしないと、テストを実行するたびに、テストによってコンテンツがダウンロードされ、ディスクにアクセスされ、メッセージがメールで送信されます。次に、メソッド内のコードをテストするだけでなく、ダウンロード、ディスクへの書き込み、およびメールの送信を行うコードもテストします。これらをモックしている場合は、メソッドコードのみをテストしています。また、たとえばダウンロードの失敗をシミュレートして、メソッドのコードが正しく動作していることを確認することもできます。

さて、偽造に関しては、私は通常、値を保持しているだけで、多くのロジックを持たない偽造クラスです。メソッドで変更されるいくつかの値を保持するオブジェクトを送信する場合は、テストでそのオブジェクトを読み取って、メソッドが正しいことを実行することを確認できます。

もちろん、ルールは少し曲げることができます(場合によっては曲げる必要があります)が、一般的な考え方は、コードをテストすることであり、コードのみをテストします。

1
crunchdog