簡體   English   中英

如何在Moq中設置重載的方法調用?

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

如果我在FooBar上注釋掉GetHashCode()重寫,或兩者都注釋掉,測試用例就會通過。 或者,如果我不使用MockFooBar ,測試用例通過。

編輯3我針對此問題打開了Moq問題347 ,其中包含更詳細的測試用例。

不確定你的FooBar類是什么樣的,但是這個測試通過了我(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM