0

我是 Moq 的新手,我想进行这样的测试:

[Fact]
        public void IsClientExternalForWebShouldReturnFalse()
        {
            // Arrange
            var request = new Mock<HttpRequestBase>();
            request.Setup(r => r.UserHostAddress).Returns(new Queue<string>(new[] { "127.0.0.1", "10.1.10.1" }).Dequeue);

            var context = new Mock<HttpContextBase>();
            context.SetupGet(c => c.Request).Returns(request.Object);

            var service = new EnvironmentService(context.Object, null);

            // Act / Assert
            service.IsClientExternal.Should().BeFalse();
            service.IsClientExternal.Should().BeFalse();
        }

它抛出这个:

------ Test started: Assembly: SAIF.Services.Tests.dll ------

Test 'SAIF.Services.Tests.EnvironmentServiceTests.IsClientExternalForWebShouldReturnFalse' failed: System.InvalidOperationException : Queue empty.
    at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
    at System.Collections.Generic.Queue`1.Dequeue()   at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
    at System.Collections.Generic.Queue`1.Dequeue()   at Moq.Extensions.InvokePreserveStack(Delegate del, Object[] args)
    at Moq.MethodCallReturn`2.Execute(ICallContext call)
    at Moq.Interceptor.Intercept(ICallContext invocation)
    at Moq.Proxy.CastleProxyFactory.Interceptor.Intercept(IInvocation invocation)
    at Castle.DynamicProxy.AbstractInvocation.Proceed()
    at Castle.Proxies.HttpRequestBaseProxy.get_UserHostAddress()
    Services\EnvironmentService.cs(54,0): at SAIF.Services.EnvironmentService.<get_IsClientExternal>b__3(String ip)
    at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
    Services\EnvironmentService.cs(54,0): at SAIF.Services.EnvironmentService.get_IsClientExternal()
    EnvironmentServiceTests.cs(25,0): at SAIF.Services.Tests.EnvironmentServiceTests.IsClientExternalForWebShouldReturnFalse()

0 passed, 1 failed, 0 skipped, took 0.69 seconds (xUnit.net 1.9.1 build 1600).

实际测试代码:

public bool IsClientExternal
        {
            get { return IsWeb && !internalAddressRoots.Any(ip => httpContext.Request.UserHostAddress.StartsWith(ip)); }
        }

但是,如果我只在它工作后才调用该服务,但该服务只获得第一个值。

此外,如果我调试并将鼠标悬停在 上httpContext.Request.UserHostAddress,则值会更改。

有任何想法吗?

编辑#1

所以我发现了我认为的问题。这个问题是被测试的实际代码循环通过所有 ip 并调用UserHostAddress. 我只需要弄清楚如何将字符串数组提供Returns()给模拟函数。

4

1 回答 1

2

您的UserHostAddress属性可能会在调用中被调用几次Any,我们不知道它会被调用多少次(取决于 的内容internalAddressRoots)。因此,当您进行第二次服务呼叫时,您的队列可能是空的。

如果你真的想测试两次,也许你应该设置两次。后续设置会覆盖之前的设置:

    public void IsClientExternalForWebShouldReturnFalse()
    {
        // Arrange
        var request = new Mock<HttpRequestBase>();
        request.Setup(r => r.UserHostAddress).Returns("127.0.0.1");

        var context = new Mock<HttpContextBase>();
        context.SetupGet(c => c.Request).Returns(request.Object);

        var service = new EnvironmentService(context.Object, null);

        // Act / Assert
        service.IsClientExternal.Should().BeFalse();

        request.Setup(r => r.UserHostAddress).Returns("10.1.10.1");
        service.IsClientExternal.Should().BeFalse();
    }

如您所见,我们将设置与断言部分混合在一起,看起来不太好,但我不确定您的动机,所以这是一种可能的解决方案。

于 2012-09-18T20:34:14.803 回答