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)。したがって、2番目のサービス呼び出しに到達するまでに、キューは空になっている可能性があります。

本当に2回テストしたい場合は、2回セットアップする必要があります。後続のセットアップは、前のセットアップをオーバーライドします。

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

ご覧のとおり、セットアップとアサート部分を組み合わせています。これはあまり見栄えがよくありませんが、動機がわからないため、考えられる解決策の1つを次に示します。

于 2012-09-18T20:34:14.803 に答える