集成测试依赖于响应cookie抛出System.NullReferenceException

时间:2015-08-13 12:10:48

标签: c# .net unit-testing testing

我正试图找到一种方法来为依赖于HttpContext并使用cookie的组件编写集成测试。

我的问题是当它尝试向响应cookie写入任何内容时抛出异常。

这是重现问题的一些代码。

using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web;
using Moq;

namespace CookieTest
{
    [TestClass]
    public class CookieTest
    {
        private Mock<HttpContextBase> _httpContextMock;

        [TestInitialize]
        public void SetUp()
        {
            var request = new HttpRequest(null, "http://localhost/", "");
            var stream = new MemoryStream();
            var sw = new StreamWriter(stream);
            var response = new HttpResponse(sw);
            _httpContextMock = new Mock<HttpContextBase>();

            _httpContextMock.Setup(t => t.Request).Returns(new HttpRequestWrapper(request));
            _httpContextMock.Setup(t => t.Response).Returns(new HttpResponseWrapper(response));
        }

        [TestMethod]
        public void TestCookieWrite()
        {
            var httpContext = _httpContextMock.Object;
            var expectedValue = "value";
            var cookies = httpContext.Response.Cookies;
            var cookieToAdd = new HttpCookie("key", expectedValue);

            // to illustrate that these are not null
            Assert.IsNotNull(cookies);
            Assert.IsNotNull(cookieToAdd);

            // System.NullReferenceException: Object reference not set to an instance of an object.
            // at System.Web.HttpCookieCollection.Add(HttpCookie cookie)
            // at CookieTest.CookieTest.TestCookieWrite() in CookieTest.cs: line 41
            cookies.Add(cookieToAdd); 

            Assert.AreEqual(expectedValue, httpContext.Response.Cookies.Get("key"));
        }
    }
}

1 个答案:

答案 0 :(得分:1)

响应包含一个名为_context的私有字段,如果您设置字段,则需要引用自身和请求:

var response = new HttpResponse(sw);
response.GetType()
        .GetField("_context", BindingFlags.NonPublic | BindingFlags.Instance)
        .SetValue(response, new HttpContext(request, response));
_httpContextMock = new Mock<HttpContextBase>();

然后将不再抛出NullReferenceException。此外,当您将HttpCookie对象与字符串进行比较时,测试失败,您需要编辑断言以检查Value属性,如下所示:

Assert.AreEqual(expectedValue, httpContext.Response.Cookies.Get("key").Value);