Search code examples
asp.net-mvc-3unit-testingmockinghttpcontext

Mocking Request.Browser.Type in Unit Tests


I am trying to test an ActionResult that returns a partial view. This action checks to see if the user is using IE7 or IE8 and will return a different partial if the user is using IE7 or 8. This is because the java-script we are using doesn't quite work with 7 or 8 so we will treat it differently.

I have left out the model creation because I want to just focus on the Request.Browser.Type.

public ActionResult ActionName(string listing)
{
    if (model.Count > 1 && Request.Browser.Type != "IE8" && Request.Browser.Type != "IE7")
    {
        return PartialView("~/Areas/Features/Views/Video/MultiVideo.cshtml", model);
    }
    return PartialView("~/Areas/Features/Views/Video/SingleVideo.cshtml", model.FirstOrDefault());
}

Ultimately I want to know two things

  1. How can you Mock the Request.Browser.Type if at all?
  2. Is this even good practice to do inside your controller? If not what solutions would be better?

What I have tried:

var browser = new Mock<HttpContext>(MockBehavior.Strict); browser.Setup(x => x.Request.Browser).Returns("IE9");


Solution

  • I answered my own question while writing the question (which I find often happens for me). However, I wasn't able to find much on this anywhere else so I figured I'd share my solution.

    With help from this SO question I came up with this to be able to Mock browser types

            var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
    
            // This line would do the job
            request.Setup(b => b.Browser.Type).Returns("IE9");
    
            var context = new Mock<HttpContextBase>();
            context.SetupGet(c => c.Request).Returns(request.Object);
    
            controller.ControllerContext = new ControllerContext(
                                                context.Object,
                                                new RouteData(),
                                                controller);
    

    I still am uncertain if this is a good idea or not to do in your controller. Any thoughts would be appreciated.