aro*_*eer 5 c# overloading moq
我正在尝试模拟映射接口IMapper:
public interface IMapper<TFoo, TBar> {
TBar Map(TFoo foo);
TFoo Map(TBar bar);
}
Run Code Online (Sandbox Code Playgroud)
在我的测试中,我将模拟映射器设置为期望每个都被调用(围绕NHibernate update操作):
//...
_mapperMock.Setup(m => m.Map(fooMock.Object)).Returns(barMock.Object);
_mapperMock.Setup(m => m.Map(barMock.Object)).Returns(fooMock.Object);
//...
Run Code Online (Sandbox Code Playgroud)
但是,在进行第二次Map调用时,映射器模拟程序将抛出异常,因为它只希望进行一次调用。
看着在运行时安装过程中的mapper模拟,我可以看到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>>();
//...
}
}
Run Code Online (Sandbox Code Playgroud)
编辑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());
}
Run Code Online (Sandbox Code Playgroud)
如果我GetHashCode()在Foo或Bar或两者上都注释掉了替代,则测试用例通过。或者,如果我不使用Mock第Foo和Bar,测试用例通过。
编辑3 我针对这个问题打开了Moq问题347,其中包含更详细的测试用例。
不确定你的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
{
}
}
Run Code Online (Sandbox Code Playgroud)