Thursday, October 6, 2011

Mocking a web context for .Net MVC using Moq

To effectively unit test MVC Controllers you'll need to supply a web context or an HttpContext object. This is a quick and dirty way to mock out a web context that can access the Request, Response, Form, and Cookies objects. They essentially become Dictionary objects for which you can stuff values in the same way normally would for a Dictionary. Those values will be there when you run your unit tests.
public class ContextMocks {
 public Moq.Mock<HttpContextBase> HttpContext { get; private set; }
 public Moq.Mock<HttpRequestBase> Request { get; private set; }
 public Moq.Mock<HttpResponseBase> Response { get; private set; }
 public RouteData RouteData { get; private set; }

 public ContextMocks(Controller onController) {
  // Define all the common context objects, plus relationships between them
  HttpContext = new Moq.Mock<HttpContextBase>();
  Request = new Moq.Mock<HttpRequestBase>();
  Response = new Moq.Mock<HttpResponseBase>();
  
  HttpContext.Setup(x => x.Request).Returns(Request.Object);
  HttpContext.Setup(x => x.Response).Returns(Response.Object);
  HttpContext.Setup(x => x.Session).Returns(new FakeSessionState());
  Request.Setup(x => x.Cookies).Returns(new HttpCookieCollection());
  Response.Setup(x => x.Cookies).Returns(new HttpCookieCollection());
  Request.Setup(x => x.QueryString).Returns(new NameValueCollection());
  Request.Setup(x => x.Form).Returns(new NameValueCollection());
  
  // Apply the mock context to the supplied controller instance
  RequestContext rc = new RequestContext(HttpContext.Object, new RouteData());
  onController.ControllerContext = new ControllerContext(rc, onController);
 }
 
 // Use a fake HttpSessionStateBase, because it's hard to mock it with Moq
 private class FakeSessionState : HttpSessionStateBase {
  Dictionary<string, object> items = new Dictionary<string, object>();
  public override object this[string name] {
   get { return items.ContainsKey(name) ? items[name] : null; }
   set { items[name] = value; }
  }
 }
}

3 comments:

  1. Genuine appreciation naturally grows whenever ValleyVistaNews shares informative updates that readers understand comfortably. The website deserves recognition for staying committed to quality content while creating a dependable platform for meaningful and enjoyable online reading.

    ReplyDelete
  2. Prosperous growth becomes easier to imagine because newscod continues sharing valuable updates regularly. The website deserves praise for maintaining clarity and informative writing while creating an enjoyable and dependable online destination for curious readers.

    ReplyDelete
  3. Remarkable writing deserves strong appreciation because dailynewslaw consistently provides helpful updates that are easy to understand. The dedication behind maintaining quality content makes this website a reliable source for visitors wanting informative and engaging material regularly.

    ReplyDelete