How I can add test cookie to request so I can test my code from Unit test. Consider a code like this:
public ActionResult Dashboard()
{
if (Request.Cookies["usercookie"] == null)
{
return RedirectToAction("Index");
}
return View();
}
I mock everything, but I don't know how I can add something to cookie so this line Request.Cookies["usercookie"]
not return null. As now it is null and returning me this error:
{"Object reference not set to an instance of an object."}
This is one of my unit test methods:
[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);
}
}
This is a class in 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;
}
Here is an example unit test where a cookie is set on the request.
Used NSubstitute framework to mock the http context and then setup the request cookies property. Applied the mocked http context to the controller context to simulate a request.
[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();
}
}
}
Update:
Here is an updated version of the test using a manually created mocked 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;
}
}
}
}
}
This is the same thing using MOQ framework
MockContext class used to mock the HTTP context
public class MockContext
{
public Mock<RequestContext> RoutingRequestContext { get; private set; }
public Mock<HttpContextBase> Http { get; private set; }
public Mock<HttpServerUtilityBase> Server { get; private set; }
public Mock<HttpResponseBase> Response { get; private set; }
public Mock<HttpRequestBase> Request { get; private set; }
public Mock<HttpSessionStateBase> Session { get; private set; }
public Mock<ActionExecutingContext> ActionExecuting { get; private set; }
public HttpCookieCollection Cookies { get; private set; }
public MockContext()
{
this.RoutingRequestContext = new Mock<RequestContext>(MockBehavior.Loose);
this.ActionExecuting = new Mock<ActionExecutingContext>(MockBehavior.Loose);
this.Http = new Mock<HttpContextBase>(MockBehavior.Loose);
this.Server = new Mock<HttpServerUtilityBase>(MockBehavior.Loose);
this.Response = new Mock<HttpResponseBase>(MockBehavior.Loose);
this.Request = new Mock<HttpRequestBase>(MockBehavior.Loose);
this.Session = new Mock<HttpSessionStateBase>(MockBehavior.Loose);
this.Cookies = new HttpCookieCollection();
this.RoutingRequestContext.SetupGet (c => c.HttpContext).Returns(this.Http.Object);
this.ActionExecuting.SetupGet (c => c.HttpContext).Returns(this.Http.Object);
this.Http.SetupGet (c => c.Request).Returns(this.Request.Object);
this.Http.SetupGet (c => c.Response).Returns(this.Response.Object);
this.Http.SetupGet (c => c.Server).Returns(this.Server.Object);
this.Http.SetupGet (c => c.Session).Returns(this.Session.Object);
this.Request.Setup (c => c.Cookies).Returns(Cookies);
}
}
and this is the test case
public void IndexTest()
{
// arrange
MockContext mockContext = new MockContext();
#region creating cookie
HttpCookie cookie = new HttpCookie(Constant.COOKIE_ADMIN_USER_INFO,
Config.DefaultCountryID.ToString());
cookie.Values.Add(Constant.COOKIE_ADMIN_VALUE_COUNTRY_ID,
Config.DefaultCountryID.ToString());
cookie.Values.Add(Constant.COOKIE_ADMIN_VALUE_LANGUAGE_ID,
Config.DefaultLanguageID.ToString());
mockContext.Cookies.Add(cookie);
#endregion
#region Creating controller
ControllerContext controllerContex = new ControllerContext()
{
HttpContext = mockContext.Http.Object
};
HomeController controller = new HomeController()
{
ControllerContext = controllerContex
};
#endregion
// act
var output = (ViewResult)controller.Index();
var result = output.ViewData;
// assert
result.ShouldNotBeNull();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With