如何在C#单元测试中将测试Cookie添加到请求中

如何添加测试Cookie以请求,以便可以从单元测试中测试代码.考虑这样的代码:

public ActionResult Dashboard()
{
    if (Request.Cookies["usercookie"] == null)
    {
        return RedirectToAction("Index");
    }
    return View();
}

我模拟了所有内容,但是我不知道如何向Cookie添加内容,因此这一行Request.Cookies [“ usercookie”]不会返回null.现在它为null并返回此错误:

{“Object reference not set to an instance of an object.”}

这是我的单元测试方法之一:

[TestMethod]
[TestCategory("Unit")]
public void Login_ShouldValidateUserAndLoginSuccessfully()
{
    using (var kernel = new NSubstituteMockingKernel())
    {
        // Setup the dependency incjection
        kernel.Load(new EntityFrameworkTestingNSubstituteModule());

        // Create test request data 
        var request = new LogInRequest { UserName = "test", Password = "test" };

        var fakeResponseHandler = new FakeResponseHandler();
        fakeResponseHandler.AddFakeResponse(new Uri("http://localhost/test"), new HttpResponseMessage(HttpStatusCode.OK));
        ConfigurationManager.AppSettings["SearchApiBaseUrl"] = "http://test/internal";
        var server = new HttpServer(new HttpConfiguration(), fakeResponseHandler);
        var httpClient = new HttpClient(server);

        var fakeCookieManager = new FakeCookieManager();
        var authenticationService = Substitute.For<IAuthenticationService>();
        var newUser = Fake.GetNewUser(1);
        var newUserClaim = Fake.GetNewUserClaim(1, newUser.Id, "http://test/identity/claims/loans");
        authenticationService.GetUserByEmailPasswordAsync(request.UserName, request.Password).Returns(newUser);
        authenticationService.GetUserClaimByEmailAndPasswordAsync(request.UserName, request.Password).Returns(newUserClaim);
        var controller = new HomeController(httpClient, fakeCookieManager, null, authenticationService);
        Fake.SetFakeAuthenticatedControllerContext(controller);
        controller.HttpContext.Session["ReturnUrl"] = "/search"; 
        var result = controller.Login(request);
        Assert.IsNotNull(result);
    }
}

这是Fake for Httpcontext中的一个类:

    public static HttpContextBase InitialiseFakeHttpContext(string url = "")
    {
        var HttpContextSub = Substitute.For<HttpContextBase>();
        var RequestSub = Substitute.For<HttpRequestBase>();
        var ResponseSub = Substitute.For<HttpResponseBase>();
        var serverUtilitySub = Substitute.For<HttpServerUtilityBase>();
        var itemsSub = Substitute.For<IDictionary>();
        HttpContextSub.Request.Returns(RequestSub);
        HttpContextSub.Response.Returns(ResponseSub);
        HttpContextSub.Server.Returns(serverUtilitySub);
        var cookie = Substitute.For<HttpResponseBase>();
        HttpContextSub.Response.Returns(cookie);
        return HttpContextSub;
    }

解决方法:

这是一个示例单元测试,其中在请求上设置了cookie.

使用NSubstitute框架模拟http上下文,然后设置请求cookie属性.将模拟的http上下文应用于控制器上下文以模拟请求.

[TestClass]
public class MyControllerTests {
    [TestMethod]
    public void Request_Cookies_Should_Not_Be_Null() {
        //Arrange
        var cookies = new HttpCookieCollection();
        cookies.Add(new HttpCookie("usercookie"));

        var mockHttpContext = Substitute.For<HttpContextBase>();
        mockHttpContext.Request.Cookies.Returns(cookies);

        var sut = new MyController();
        sut.ControllerContext = new ControllerContext {
            Controller = sut,
            HttpContext = mockHttpContext
        };

        //Act
        var result = sut.Dashboard() as ViewResult;

        //Assert
        Assert.IsNotNull(result);
    }

    public class MyController : Controller {
        public ActionResult Dashboard() {
            if (Request.Cookies["usercookie"] == null) {
                return RedirectToAction("Index");
            }
            return View();
        }
    }
}

更新:

这是使用手动创建的模拟HttpContext进行的测试的更新版本.

[TestClass]
public class MyControllerTests {
    [TestMethod]
    public void Request_Cookies_Should_Not_Be_Null() {
        //Arrange
        var cookies = new HttpCookieCollection();
        cookies.Add(new HttpCookie("usercookie"));

        var mockHttpContext = new MockHttpContext(cookies);

        var sut = new MyController();
        sut.ControllerContext = new ControllerContext {
            Controller = sut,
            HttpContext = mockHttpContext
        };

        //Act
        var result = sut.Dashboard() as ViewResult;

        //Assert
        Assert.IsNotNull(result);
    }

    public class MyController : Controller {
        public ActionResult Dashboard() {
            if (Request.Cookies["usercookie"] == null) {
                return RedirectToAction("Index");
            }
            return View();
        }
    }


    private class MockHttpContext : HttpContextBase {
        private readonly MockRequest request;
        public MockHttpContext(HttpCookieCollection cookies) {
            this.request = new MockRequest(cookies);
        }

        public override HttpRequestBase Request {
            get {
                return request;
            }
        }

        public class MockRequest : HttpRequestBase {
            private readonly HttpCookieCollection cookies;
            public MockRequest(HttpCookieCollection cookies) {
                this.cookies = cookies;
            }

            public override HttpCookieCollection Cookies {
                get {
                    return cookies;
                }
            }
        }

    }
}
上一篇:C#单元测试-模拟,存根或使用显式实现


下一篇:c# – Nunit,NCrunch和NSubstitute – 使用UnexpectedArgumentMatcherException总是2次测试失败,它随机改变(准)