web-dev-qa-db-ja.com

Moqは1つのメソッドを偽造しますが、別のメソッドの実際の実装を使用します

Method1()およびMethod2()を持つインターフェースIServiceが与えられた場合。

Method1()Exceptionをスローしたときに、_Method2(_)が呼び出され、指定された値を返すであることをテストしたい。

Method2()がスローされると、Method1()が呼び出されます)。

したがって、偽のMethod2()で実際のMethod1()をテストする必要があります。これらは同じインターフェースのメソッドです。

これが私のテストコードです。

MBase sut.MethodX()は唯一のエントリポイントです。 IServiceを使用します。

私の目的は、Method2()somethingを返すことをアサートすることです。

_// Arrange
// Fake bytes in.
var networkStreamMock = new Mock<INetworkStream>();
networkStreamMock.Method1(x => x.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>())).Returns(It.IsAny<byte[]>());

// Force throw TimeoutException.
var mock = new Mock<IService>();
mock.Setup(x => x.Method1(new Message
{ 
    Xml = Xml,  
}
)).Throws<TimeoutException>();

// Check Method 2 is called. (this is done in its own test so commented out)
// mock.Setup(m => m.Method2(It.IsAny<Message>())).Verifiable();

// New MBase.
IKernel kernel = new StandardKernel(new FakeBindings());
kernel.Rebind<IService>().ToConstant(mock.Object);
MBase sut = kernel.Get<M>();

// Act
sut.MethodX(networkStreamMock.Object);

// Here I would like to assert on the return value of Method2
mock.Verify(m => m.Method2(It.IsAny<Message>()));
_

これはMoqまたは別のモックフレームワークで可能ですか?どうすればいいのですか? Method1()の偽の実装とMethod2()の実際の実装を使用して手動のモックを作成できますが、より良いアプローチがあるのではないかと思います。

私はすでにIServiceを単独でテストしましたが、MBaseとの相互作用をテストしたいと思います。

37
Sam Leach

この場合(さらに多くのことがない限り)、モックに必要なインターフェイスを実装する実際の動作でクラスを拡張する独自のテストクラスを作成します。この方法で、1つの値をモックし、実際の機能のために基本クラスにフォールバックできます。

8
Chris Missal