我正试图找到一种方法来为依赖于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"));
}
}
}
答案 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);