如何添加测试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;
}
}
}
}
}