我正在尝试模拟映射接口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);
//...
但是,当进行第二次Map
调用时,映射器模拟会抛出,因为它只需要一次调用。
在运行时设置期间观看映射器模拟,我可以看到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()
覆盖,则测试用例通过。或者,如果我不使用and ,则测试用例通过。Foo
Bar
Mock
Foo
Bar
编辑 3 我针对这个问题打开了Moq Issue 347,其中包含更详细的测试用例。