Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

Fakes FrameworkとMoqめもめも

$
0
0

Fakes Framework一択でもいいけど、Premium以上なのよね~。高いわ~。ということで、現実解はMoq。

Fakesのほうがよさげな点

staticなメソッドや非virtualなメソッドとかも差し替え出来る。テスト?なんですかそれ?というようなコードでも強引にモックに差し替え出来る。

Moqのほうがよさげな点

モックのメソッドが意図したとおりに、使われたかの確認が出来る。

お試し

こんなテスト対象のクラスがあったとして。

publicclass Calc
{
    publicvirtualint Add(int x, int y) { return x + y; }
}

テストコードは各々こんな感じになる。

[TestClass]
publicclass UnitTest1
{
    [TestMethod]
    publicvoid ShimsMethod()
    {
        using (ShimsContext.Create())
        {
            ShimCalc.AllInstances.AddInt32Int32 = (c, x, y) =>
            {
                Assert.AreEqual(10, x);
                Assert.AreEqual(20, y);
                return10;
            };
            Assert.AreEqual(10, new Calc().Add(10, 20));
        }
    }

    [TestMethod]
    publicvoid StubMethod()
    {
        var stub = new StubCalc
        {
            AddInt32Int32 = (x, y) =>
            {
                Assert.AreEqual(10, x);
                Assert.AreEqual(20, y);
                return10;
            }
        };

        Assert.AreEqual(10, stub.Add(10, 20));
    }

    [TestMethod]
    publicvoid MoqMethod()
    {
        var moq = new Mock<Calc>();
        moq.Setup(c => c.Add(10, 20)).Returns(10);

        Assert.AreEqual(10, moq.Object.Add(10, 20));
        moq.VerifyAll();
    }
}

FakesのStubとMoqのMockを比べるとMoqのほうが高機能っぽい(意図したとおりの呼び出されたかどうかの確認が出来る点で)ですが、Shimsは、ShimsContextの中だったら、staticなメソッドだろうと非virtualなメソッドだろうと、結果を差し替えることが出来る。

上のコードの中では、ShimsMethodだけがCalcクラスのAddがvirtualじゃなくても動作する。あとはSystemu名前空間のクラスとかもShimsで呼び出し結果を意図したものに差し替え出来る。何それ怖い。

個人的なまとめ

Premium以上ならおとなしくFakes使ったほうが強力っぽいし、無駄にインターフェース作ったりとかしなくてもテストは可能になるあたり、つぶしが効きそう。Moqでもテストできるような形(Interfaceきっとくとかvirtualにしておくとか、DateTime.Nowとかはラップしたものを用意しておくとかetc...)にする条件(人的にもお金的にも体制的にも…)が整ってるならMoqでいいんじゃにあかなぁとまとまりのないことを書きましたが、端的にいうとMoqとFakesの記憶を将来の自分が辿るためのコード片メモでした。

リンク


Viewing all articles
Browse latest Browse all 1387

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>