[英]How can I Setup overloaded method invocations in Moq?
我正在嘗試模擬映射接口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());
}
如果我在Foo
或Bar
上注釋掉GetHashCode()
重寫,或兩者都注釋掉,測試用例就會通過。 或者,如果我不使用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
{
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.