マッピングインターフェースをモックしようとしていますIMapper
:
public interface IMapper<TFoo, TBar> {
TBar Map(TFoo foo);
TFoo Map(TBar bar);
}
私のテストでは、(NHibernateupdate
操作の周りで)それぞれの呼び出しを期待するようにモックマッパーを設定しています:
//...
_mapperMock.Setup(m => m.Map(fooMock.Object)).Returns(barMock.Object);
_mapperMock.Setup(m => m.Map(barMock.Object)).Returns(fooMock.Object);
//...
ただし、2回目のMap
呼び出しが行われると、マッパーモックは1回の呼び出しのみを想定しているため、スローします。
実行時のセットアップ中にマッパーモックを見ると、オーバーロードが登録され、オーバーロードがセットアップされたMap(TFoo foo)
ときに置き換えられることがわかります。Map(TBar bar)
これはMoqがセットアップを処理する方法に問題がありますか、それともこの場合に使用する必要のある別の構文がありますか?
編集 これは、テストコンストラクターからの実際のインスタンス化コードです。
public class TestClass {
private readonly MockRepository _repository = new MockRepository(MockBehavior.Strict);
public TestClass() {
//...
_mapperMock = _repository.Create
<IMapper<RequestData.Foo, ResponseData.Bar>>();
//...
}
}
編集2
完全に失敗したテストケースは次のとおりです。
public interface IMapper<TFoo, TBar> {
TFoo Map(TBar bar);
TBar Map(TFoo foo);
}
public class Foo {
public override int GetHashCode() {
// return base.GetHashCode();
return 1;
}
}
public class Bar {
public override int GetHashCode() {
// return base.GetHashCode();
return 2;
}
}
[Test]
public void TestIt()
{
// Arrange
var _mapperMock = new Mock<IMapper<Foo, Bar>>(MockBehavior.Strict);
var fooMock = new Mock<Foo>();
var barMock = new Mock<Bar>();
_mapperMock.Setup(m => m.Map(fooMock.Object)).Returns(barMock.Object);
_mapperMock.Setup(m => m.Map(barMock.Object)).Returns(fooMock.Object);
// Act - breaks on first line below this comment
var bar = _mapperMock.Object.Map(fooMock.Object);
var foo = _mapperMock.Object.Map(barMock.Object);
// Assert
_mapperMock.Verify(x => x.Map(fooMock.Object), Times.Once());
_mapperMock.Verify(x => x.Map(barMock.Object), Times.Once());
}
いずれか、または両方のGetHashCode()
オーバーライドをコメントアウトすると、テストケースは合格です。または、とのsを使用しない場合、テストケースは合格です。Foo
Bar
Mock
Foo
Bar
編集3 私はこの問題に対してMoqIssue347を開き、より詳細なテストケースを用意しました。