我正在尝试模拟映射接口IMapper
:
public interface IMapper<TFoo, TBar> {
TBar Map(TFoo foo);
TFoo Map(TBar bar);
}
在我的测试中,我将模拟映射器设置为期望调用每个(在NHibernate update
操作周围):
//...
_mapperMock.Setup(m => m.Map(fooMock.Object)).Returns(barMock.Object);
_mapperMock.Setup(m => m.Map(barMock.Object)).Returns(fooMock.Object);
//...
但是,当进行第二次Map
调用时,mapper mock会抛出,因为它只需要一次调用。
在运行时设置期间观察映射器模拟,我可以看到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()
或Foo
或两者上注释Bar
覆盖,则测试用例通过。或者,如果我不使用Mock
和Foo
的{{1}},则测试用例会通过。
编辑3 我打开了Moq Issue 347来解决这个问题,并提供了更详细的测试用例。
答案 0 :(得分:2)
不确定你的Foo
和Bar
类是什么样的,但是这个测试通过了我(Moq 4.0.10827.0,这是NuGet中的最新版本)
using Moq;
using NUnit.Framework;
namespace ConsoleApplication1
{
[TestFixture]
public class Tests
{
[Test]
public void TestIt()
{
// Arrange
var _mapperMock = new Mock<IMapper<Foo, Bar>>();
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
var bar = _mapperMock.Object.Map(fooMock.Object);
var foo = _mapperMock.Object.Map(barMock.Object);
// Assert
Assert.AreSame(bar, barMock.Object);
Assert.AreSame(foo, fooMock.Object);
_mapperMock.Verify(x => x.Map(fooMock.Object), Times.Once());
_mapperMock.Verify(x => x.Map(barMock.Object), Times.Once());
}
}
public class Bar
{
}
public class Foo
{
}
}