web-dev-qa-db-ja.com

モックフレームワークとMS Fakesフレームワーク

NMockとVS 2011 Fakes FrameworkのようなMockフレームワークの違いについて少し混乱しています。 MSDNを見ると、FakesはRhinoMockやNMockのように依存関係をモックできることを理解していますが、アプローチは異なりますが、Fakesはこの機能を実現するコードを生成しますが、Mocksフレームワークはそうではありません。だから私の理解は正しいですか?偽物は単なるモックフレームワークです

91

あなたの質問は、MS FakesフレームワークがNMockとどのように異なるかについてであり、他の答えはその一部を解決したように見えますが、ここでそれらが同じであり、どのように異なるかについてのいくつかの情報があります。 NMockはRhinoMocksやMoqにも似ているため、NMockでグループ化します。

NMock/RhinoMocks/MoqとMS Fakes Frameworkには、3つの大きな違いがあります。

  • MS偽造フレームワークは、ジェネリック型ではなく、以前のバージョンのVisual Studioのアクセサーによく似た生成コードを使用します。依存関係に偽のフレームワークを使用する場合、依存関係を含むアセンブリをテストプロジェクトの参照に追加し、右クリックしてテストダブル(スタブまたはシム)を生成します。次に、テストするときに、実際にこれらの生成されたクラスを代わりに使用します。 NMockはジェネリックを使用して同じことを実現します(つまり、IStudentRepository studentRepository = mocks.NewMock<IStudentRepository>())。私の意見では、MS Fakesフレームワークアプローチは、実際のインターフェイスではなく、生成されたクラスに対して実際に作業しているため、テスト内からのコードナビゲーションとリファクタリングを禁止します。

  • MS偽物フレームワークはスタブとモグラ(シム)を提供しますが、NMock、RhinoMocks、およびMoqはすべてスタブとmocksを提供します。私は、モックを含めないというMSの決定を本当に理解していません。私は、個人的には、以下に説明する理由でモグラのファンではありません。

  • MS偽造フレームワークでは、スタブ化するメソッドの代替実装を提供します。これらの代替実装内で、戻り値を指定し、メソッドが呼び出された方法または呼び出されたかどうかに関する情報を追跡できます。 NMock、RhinoMocks、およびMoqを使用して、モックオブジェクトを生成し、そのオブジェクトを使用して、スタブ化された戻り値を指定したり、インタラクション(メソッドが呼び出されたかどうか)を追跡したりします。 MSの偽物のアプローチは、より複雑で表現力に欠けています。

フレームワークが提供するものの違いを明確にするために:NMock、RhinoMocks、およびMoqはすべて、2種類のテストダブル(スタブとモック)を提供します。偽物フレームワークはスタブとモグラ(それらをシムと呼びます)を提供しますが、残念ながらモックは含まれません。 NMockとMS Fakesの違いと類似点を理解するために、これらの異なる種類のテストダブルが何であるかを理解することは役立ちます。

スタブ:スタブは、テスト対象のメソッドによってテストの倍増が求められるメソッドまたはプロパティの値を提供する必要がある場合に使用されます。たとえば、テスト対象のメソッドがIStudentRepositoryテストダブルのDoesStudentExist()メソッドを呼び出す場合、trueを返します。

NMockとMSの偽物のスタブの考え方は同じですが、NMockでは次のようになります。

Stub.On(mockStudentRepository).Method("DoesStudentExist").Will(Return.Value(true));

MSFakesを使用すると、次のようになります。

IStudentRepository studentRepository = new DataAccess.Fakes.StubIStudentRepository() // Generated by Fakes.
{
    DoesStudentExistInt32 = (studentId) => { return new Student(); }
};

MS Fakesの例では、DoesStudentExistメソッドの完全に新しい実装を作成していることに注意してください(DoesStudentExistInt32と呼ばれることに注意してください)テスト)。正直に言うと、NMockの実装は、メソッド名を識別するために文字列を使用するため、私を悩ませます。 (NMockの使用方法を誤解している場合はご遠慮ください。)このアプローチはリファクタリングを実際に禁止するため、この理由からNMockよりもRhinoMocksまたはMoqを強くお勧めします。

モック:モックは、テスト中のメソッドとその依存関係の間の相互作用を検証するために使用されます。 NMockでは、次のような期待値を設定してこれを行います。

Expect.Once.On(mockStudentRepository).Method("Find").With(123);

これがNMockよりもRhinoMocksとMoqを好むもう1つの理由です。NMockは古い期待スタイルを使用しますが、RhinoMocksとMoqはどちらも、このようなテストの終わりにアサーションとして期待される相互作用を指定するArrange/Act/Assertアプローチをサポートします:

stubStudentRepository.AssertWasCalled( x => x.Find(123));

繰り返しますが、RhinoMocksは文字列ではなくラムダを使用してメソッドを識別することに注意してください。 ms fakesフレームワークは、モックをまったく提供しません。これは、スタブアウトされた実装(上記のスタブの説明を参照)で、後で正しく設定されたことを確認する変数を設定する必要があることを意味します。これは次のようになります。

bool wasFindCalled = false;

IStudentRepository studentRepository = new DataAccess.Fakes.StubIStudentRepository() 
{
    DoesStudentExistInt32 = (studentId) => 
        { 
            wasFindCalled = true;
            return new Student(); 
        }
};

classUnderTest.MethodUnderTest();

Assert.IsTrue(wasFindCalled);

このアプローチは、スタブで呼び出しを追跡し、後でテストでアサートする必要があるため、少し複雑になっています。 NMock、特にRhinoMocksの例は、より表現力豊かだと思います。

モグラ(シム):率直に言って、私はモグラが悪用される可能性があるので好きではありません。ユニットテスト(特にTDD)で私が気に入っていることの1つは、コードをテストすることで、どこで悪いコードを書いたかを理解するのに役立つということです。これは、不完全に記述されたコードのテストが難しいためです。モグラは実際には、注入されていない依存関係をテストしたり、プライベートメソッドをテストしたりできるように設計されているため、これは当てはまりません。これらは、次のようなShimsContextを使用することを除いて、スタブと同様に機能します。

using (ShimsContext.Create())
{
    System.Fakes.ShimDateTime.NowGet = () => { return new DateTime(fixedYear, 1, 1); };
}

シムに関する私の心配は、人々が「簡単な単体テストの方法」としてそれらを見るようになることです。なぜなら、それはあなたがあなたがするべき方法でコードを書くことを強制しないからです。この概念に関するより完全な記事については、私の次の投稿を参照してください。

偽物フレームワークに関連する懸念事項の詳細については、次の投稿をご覧ください。

RhinoMocksの学習に興味がある場合は、Pluralsightトレーニングビデオをご覧ください(完全開示-このコースを作成し、視聴回数に応じて使用料を支払っていますが、この議論に適用されると思うので、ここに含めます)。

180
Jim Cooper

あなたは正しいですが、物語にはもっとあります。この回答から最も重要なことは次のとおりです。

  1. お使いのアーキテクチャは、Fakesとmocksの松葉杖に頼るのではなく、スタブと依存性注入を適切に使用する必要があります

  2. 偽物やモックは、次のような、変更すべきでないコードや変更できないコードのテストに役立ちます

    • スタブを使用しない(または効率的に使用しない)レガシーコード
    • サードパーティAPI
    • ソースコードがないリソース

Shims(開発中は「Moles」として知られる)は、実際には迂回呼び出しによって動作するモックフレームワークです。苦労してモックを作成する代わりに(はい、Moqを使用するのは比較的苦痛です!)、シムは既に所定のプロダクションコードオブジェクトを使用します。シムは、呼び出しをプロダクションターゲットからテストデリゲートに単純に再ルーティングします。

スタブは、ターゲットプロジェクトのインターフェイスから生成されます。スタブオブジェクトはまさにそれです-インターフェイスの実装です。スタブタイプを使用する利点は、テストプロジェクトに多くの1回限りのスタブを使用することなく、スタブをすばやく生成できることです。もちろん、多くのテストで使用するために、具体的なスタブを作成する必要があります。

フェイク(Shims、Mocks、Stubタイプ)を効率的に実装するには少し慣れる必要がありますが、努力する価値は十分にあります。 Shims/Mole、Mock、およびStubタイプを使用することで、個人的に数週間の開発時間を節約しました。あなたが私と同じくらいテクノロジーを楽しんでくれることを願っています!

23
Mike Christian

私の理解では、Visual Studioチームは、.NETで利用可能なさまざまなモックライブラリとの競合を避けたいと考えていました。 MSはしばしばこのような難しい決定に直面します。特定の機能を提供しない場合(「MSがモックライブラリを提供しないのはなぜですか。モックはそんなに一般的な要件ですか?」)常にではありませんが、非常に多くの場合、彼らは、利用可能で評判の高い技術に対する独自の代替物を提供することを単に控えることを決めます。それはここの場合のようです。

フェイクのシム機能は本当に便利です。確かに、危険があります。必要な場合にのみこれを使用するには、ある程度の規律が必要です。しかし、それは大きなギャップを埋めます。私の主な不満は、VS 2012のUltimateエディションでのみ提供されるため、.NET開発コミュニティのサブセクションでのみ利用できるということです。お気の毒に。

15
Charles Young

偽物には、2種類の「偽物」オブジェクトが含まれます。 「スタブ」と呼ばれる最初のものは、本質的に自動生成されたダミーであり、そのデフォルトの動作をオーバーライドして、より興味深いモックにすることができます(通常はオーバーライドされます)。ただし、現在利用可能なモックフレームワークのほとんどが提供する機能の一部が欠けています。たとえば、スタブインスタンスのメソッドが呼び出されたことを確認する場合は、このロジックを自分で追加する必要があります。基本的に、今自分のモックを手動で作成している場合、スタブはおそらく改善のように思えます。ただし、既にフル機能のモックフレームワークを使用している場合は、Fakesスタブからいくつかの重要な部分が欠落しているように感じるかもしれません。

「シム」と呼ばれる、Fakesが提供するオブジェクトのもう1つのカテゴリは、モックによる標準的な置換のために適切に分離されていない(または分離できない)依存関係の動作を置換するメカニズムを公開します。知る限りでは、TypeMockは、この種の機能を現在提供している主要なモックフレームワークの1つです。

ところで、もしあなたが以前にMolesを試してみたなら、Fakesは本質的に同じものであり、最終的にMicrosoft Researchから抜け出て実際の製品になりました。

13
Nicole Calinoiu

フェイク(Shim + Stub)オブジェクトに関しては、上記で十分に定義されていますが、最後のコメントの最後の段落は状況全体をかなりうまく要約していると思います。

多くの人は、Fake(Shim + Stub)オブジェクトはいくつかのユニットテストケースで持つには良い資産であると主張しますが、欠点は、Visual Studio 2012またはVisual Studio 2013を使用している場合でも、これらのオプションのみが利用可能であることですPremiumまたはUltimateバージョン。 IOW、これは、どのProバージョンでもこれらの偽物(Shim + Stub)を実行しないことを意味します。

たぶん、ProバージョンでFakes(Shim + Stub)メニューオプションが表示されるかもしれませんが、絶対に何もなくなる可能性があることに注意してください。重要なことを伝えるコンパイルエラーは生成されません。不足している、オプションはそこにないので、あなたの時間を無駄にしないでください...

開発チームで考慮する必要がある重要な要素は、特にUltimateバージョンを使用しているのが1つだけで、他の人はProバージョンを使用している場合です...一方、Moqは、使用するVisual Studioバージョンに関係なく、Nugetを使用して簡単にインストールできますMoqを使用しても問題はありませんでした。ツールの重要な点は、Moqの使用目的と適切な使用方法を知ることです;)

1
SirXamelot