How to configure overloaded method calls in Moq?

I am trying to make fun of the IMapper display IMapper :

 public interface IMapper<TFoo, TBar> { TBar Map(TFoo foo); TFoo Map(TBar bar); } 

In my test, I install mock mapper to wait for everyone to call (around the NHibernate update operation):

 //... _mapperMock.Setup(m => m.Map(fooMock.Object)).Returns(barMock.Object); _mapperMock.Setup(m => m.Map(barMock.Object)).Returns(fooMock.Object); //... 

However, when the second Map call is made, the map mapper throws because it expects only one call.

Observing the variability of the display during installation at runtime, I can see how the Map(TFoo foo) overload is registered, and then see it replaced when the Map(TBar bar) overload is configured.

Is this a problem with installing Moq, or is there another syntax that I need to use in this case?

EDIT Here is the actual instance code from the test constructor:

 public class TestClass { private readonly MockRepository _repository = new MockRepository(MockBehavior.Strict); public TestClass() { //... _mapperMock = _repository.Create <IMapper<RequestData.Foo, ResponseData.Bar>>(); //... } } 

EDIT 2

Here is a complete test case:

 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()); } 

If I comment on the redefinition of GetHashCode() on Foo or Bar , or both, the test case passes. Or, if I do not use Mock from Foo and Bar , the test case passes.

EDIT 3 I opened Moq Issue 347 against this problem with more detailed test cases.

+4
source share
1 answer

I don’t know what your Foo and Bar classes look like, but this test passes for me (Moq 4.0.10827.0, which is the newest in 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 { } } 
0
source

All Articles