NUnit.Mocks.Mock を継承してモックを自作

こんなインターフェイスがあって

public interface IHoge
{
    bool Piyo();
}

こんなクラスで使用するとする。

public class Fuga
{
    private IHoge _hoge;
    public Fuga(IHoge hoge)
    {
        this._hoge = hoge;
    }
    public bool HogePiyo()
    {
        return this._hoge.Piyo();
    }
}

自前モックはこんな風に実装して

public class HogeMock : Mock, IHoge
{
    public bool Piyo()
    {
        object r = this.Call("Piyo");
        if (r != null)
        {
            return (bool)r;
        }
        return true;
    }
}

こんな風に使用できる。

[TestFixture]
public class TestFixture1
{
    [Test]
    public void Test1()
    {
        HogeMock hogeMock = new HogeMock();
        hogeMock.Strict = true;
        hogeMock.Expect("Piyo");

        Fuga f = new Fuga(hogeMock);
        bool b = f.HogePiyo();

        Assert.That(b, Is.True);
        hogeMock.Verify();
    }
    [Test]
    public void Test2()
    {
        HogeMock hogeMock = new HogeMock();
        hogeMock.Strict = true;
        hogeMock.ExpectAndReturn("Piyo", false);

        Fuga f = new Fuga(hogeMock);
        bool b = f.HogePiyo();

        Assert.That(b, Is.False);
        hogeMock.Verify();
    }
    [Test]
    [ExpectedException(typeof(InvalidOperationException))]
    public void Test3()
    {
        HogeMock hogeMock = new HogeMock();
        hogeMock.Strict = true;
        hogeMock.ExpectAndThrow("Piyo", new InvalidOperationException());

        Fuga f = new Fuga(hogeMock);
        f.HogePiyo();
    }
}

DynamicMock を使う場合と比べて、実装を持たせられることが大きな利点。つまり、"モック兼フェイク" として振る舞うことができる。