6

在过去的几个小时里,我试图弄清楚这个 Moq 体操。我有以下课程 - 我正在尝试进行一些简单的验证并且它失败了 - 我似乎无法弄清楚为什么。

请注意,在 Moq 设置期间,我在请求 BeginCounter 时返回一个 Mock.Of - 但是当我尝试验证它时它失败了。但是,如果我取消注释 p.Setup(e => e.BeginCounter.Increment()) 行,则验证有效。

我错过了什么?

public interface IPerformanceCounters
{
    void Increment();
    void Decrement();
}

public interface IContext
{
    IPerformanceCounters BeginCounter { get; }
}

public class Test
{
    private readonly IContext context;
    public Test(IContext context) { this.context = context; }
    public void React() { this.context.BeginCounter.Increment(); }
}

void Test()
{
    // ARRANGE
    var p = new Mock<IContext>();
    p.Setup(e => e.BeginCounter).Returns(() => Mock.Of<IPerformanceCounters>());  // This does not work
    // p.Setup(e => e.BeginCounter.Increment()); // However, this works!

    // ACT
    var test = new Test(p.Object);
    test.React();

    // ASSERT
    p.Verify(v => v.BeginCounter.Increment(), Times.Once());
}
4

1 回答 1

3

我相信这是因为非设置方法是不可验证的。

据我所知,您正在返回一个模拟,然后尝试对其进行验证。但是,在您取消注释设置之前,它还没有准备好。

void Test()
{
    // ARRANGE
    var p = new Mock<IContext>();
    var perfCountMock = new Mock<IPerformanceCounters>();
    p.Setup(e => e.BeginCounter).Returns(() => perfCountMock.Object);  // This does not work
    perfCountMock.Setup(e => e.Increment());

    // ACT
    var test = new Test(p.Object);
    test.React();

    // ASSERT
    perfCountMock.Verify(v => v.Increment(), Times.Once());
}

以上是你真正在做的事情。您不是在验证IContext呼叫,而是在验证IPerformanceCounters呼叫。我会以这种方式进行设置,以便更容易理解,但您可以轻松地取消注释该行

如果你想保持原样,你需要更好地理解它的Mock.Of功能。

void Test()
{
        // ARRANGE
        var p = new Mock<IContext>();
        var mockOfPerf = Mock.Of<IPerformanceCounters>();
        p.Setup(e => e.BeginCounter).Returns(mockOfPerf);  // This does not work

        // ACT
        var test = new Test1(p.Object);
        test.React();

                    // ASSERT
        Mock.Get(mockOfPerf).Verify(v=>v.Increment(), Times.Once());
}

这和上面是一样的,只是使用Mock.Of. 您无法验证嵌套模拟,您需要根据实际模拟进行验证

于 2012-11-20T03:21:49.737 回答