Friday 27 February 2015

Unit Testing ASP.NET MVC - Cheat Sheet

Mocking Request Cookie
var mockContext = new Mock<ControllerContext>();

mockContext.Setup(c => c.HttpContext.Request.Cookies).Returns(new HttpCookieCollection { new HttpCookie("test", "1") });

HomeController controller = new HomeController();
controller.ControllerContext = mockContext.Object;

var result = controller.Index()
Mocking Response Cookie
var mockContext = new Mock<ControllerContext>();

mockContext.SetupGet(c => c.HttpContext.Response.Cookies).Returns(new HttpCookieCollection());

HomeController controller = new HomeController();
controller.ControllerContext = mockContext.Object;

var result = controller.Index()

Assert.AreEqual(controller.ControllerContext.RequestContext.HttpContext.Response.Cookies["test"].Value, "1");

Mocking Request.IsAuthenticated
var mockContext = new Mock<ControllerContext>();
mockContext.SetupGet(x => x.HttpContext.User.Identity.Name).Returns("SOMEUSER");
mockContext.SetupGet(x => x.HttpContext.Request.IsAuthenticated).Returns(true);

var controller = new HomeController();
controller.ControllerContext = mockContext.Object;
Mocking ModeState.IsValid

ModeState.IsValid property is read only. But you can add an error to the ModelState to set the IsValid flag false indirectly.

var controller = new HomeController();
controller.ModelState.AddModelError("Error", "Model is invalid");
ViewResult result = controller.Index() // ModeState.IsValid will be false when Index() is executed. 
Mocking Dependency

MathController depends on an implementation of IMathService to complete the action. In the following example a mock instance of IMathService is passed to MathController to test the Add() method

Mock mathService = new Mock<IMathService>();
mathService.Setup(ms => ms.Add(1, 2)).Returns(3);

MathController controller = new MathController(mathService.Object);
var result = controller.Index(1, 2) as ViewResult;

Assert.AreEqual(result.ViewBag.Sum, 3);
mathService.Verify(ms => ms.Add(1,2), Times.Exactly(1));
Mocking Exception
Mock mathService = new Mock<IMathService>();
mathService.Setup(ms => ms.Add(1, 0)).Throws(new ArgumentException("Invalid argument(s)"));

MathController controller = new MathController(mathService.Object);

try
{
      var result = controller.Index(1, 0) as ViewResult;
}
catch(ArgumentException ex)
{
      Assert.AreEqual("Invalid argument(s)", ex.Message);
}
Testing RedirectResult

If your method returns a RedirectResult then you can check the result url against the expected

var controller = new RedirectController();

RedirectResult result = controller.SendMeSomewhereElse();

Assert.AreEqual("~/Some/Other/Place", result.Url);
Testing RedirectToRouteResult

If your method returns a RedirectToRoute i.e. if your action method returns RedirectToAction() or RedirectToRoute() then you can check the action name in RouteValues against the expected value. In the following example CustomerController.Create() is tested to check if the request is redirected to Index after creating the customer.

 var controller = new CustomerController();

var result = controller.Create(new Customer {Name = "Test"}) as RedirectToRouteResult;

Assert.AreEqual("Index", result.RouteValues["action"]);

Mocking HttpContext

Click here to see how to Mock HttpContext

No comments:

Post a Comment