簡體   English   中英

使用Moq和Linq Any()

[英]Using Moq with Linq Any()

我有類似下面的設置:

    [TestMethod]
    public void NoIntegers()
    {
        Mock<IBar> mockBar = new Mock<IBar>(MockBehavior.Strict);
        Mock<IEnumerable<int>> mockIntegers = new Mock<IEnumerable<int>>(MockBehavior.Strict);

        mockBar
            .SetupGet(x => x.Integers)
            .Returns(mockIntegers.Object);

        mockIntegers
            .Setup(x => x.Any())
            .Returns(false);

        Assert.IsFalse(new Foo(mockBar.Object).AreThereIntegers());
    }

    public interface IBar
    {
        IEnumerable<int> Integers { get; }
    }

    public class Foo
    {
        private IBar _bar;

        public Foo(IBar bar)
        {
            _bar = bar;
        }

        public bool AreThereIntegers()
        {
            return _bar.Integers.Any();
        }
    }
}

當它運行時,它無法初始化模擬

Test method NoIntegers threw exception: System.NotSupportedException: Expression references a method that does not belong to the mocked object: x => x.Any<Int32>()

我嘗試以幾種形式添加It.IsAny()

mockIntegers
    .Setup(x => x.Any(It.IsAny<IEnumerable<int>>(), It.IsAny<Func<int, bool>>()))
    .Returns(false);

// No method with this signiture


mockIntegers
    .Setup(x => x.Any(It.IsAny<Func<int, bool>>()))
    .Returns(false);

// Throws: Test method NoIntegers threw exception: 
// System.NotSupportedException: 
// Expression references a method that does not belong to the mocked object:
//  x => x.Any<Int32>(It.IsAny<Func`2>())

為了讓它運行,我需要模擬什么?

您只需要模擬Integers屬性。 沒有必要模擬Any() (你不能這樣做,因為它是一個擴展方法),因為它是SUT的一部分。 以下是您應該如何處理兩種情況:

[TestMethod]
public void NoIntegers()
{
    Mock<IBar> mockBar = new Mock<IBar>(MockBehavior.Strict);

    mockBar.SetupGet(x => x.Integers)
           .Returns(new List<int>());

    Assert.IsFalse(new Foo(mockBar.Object).AreThereIntegers());
}

[TestMethod]
public void HasIntegers()
{
    Mock<IBar> mockBar = new Mock<IBar>(MockBehavior.Strict);

    mockBar.SetupGet(x => x.Integers)
           .Returns(new List<int>{ 3, 5, 6});

    Assert.IsTrue(new Foo(mockBar.Object).AreThereIntegers());
}

它不起作用,因為Any()方法不是由IEnumerable<T>接口直接公開的,而是Enumerable定義為擴展方法

我不認為你可以在任何模擬上設置對Any()的調用,因為它本質上是一個靜態方法。

在這種情況下,我認為最好使用IEnumerable<int> (例如:int數組)的實例,可以設置為空/非空,具體取決於您正在測試的內容。

固定!

不漂亮,但這是需要的嘲弄:

   [TestMethod]
    public void NoIntegers()
    {
        Mock<IBar> mockBar = new Mock<IBar>(MockBehavior.Strict);
        Mock<IEnumerable<int>> mockIntegers = new Mock<IEnumerable<int>>(MockBehavior.Strict);
        Mock<IEnumerator<int>> mockEnumerator = new Mock<IEnumerator<int>>(MockBehavior.Strict);
        mockBar
            .SetupGet(x => x.Integers)
            .Returns(mockIntegers.Object);

        mockIntegers
            .Setup(x => x.GetEnumerator())
            .Returns(mockEnumerator.Object);

        mockEnumerator.Setup(x => x.MoveNext()).Returns(false);

        mockEnumerator.Setup(x => x.Dispose());

        Assert.IsFalse(new Foo(mockBar.Object).AreThereIntegers());
    }

    public interface IBar
    {
        IEnumerable<int> Integers { get; }
    }

    public class Foo
    {
        private IBar _bar;

        public Foo(IBar bar)
        {
            _bar = bar;
        }

        public bool AreThereIntegers()
        {
            return _bar.Integers.Any();
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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