[C#] Mock HttpContext.Current in Test Init Method


Answers

Below Test Init will also do the job.

[TestInitialize]
public void TestInit()
{
  HttpContext.Current = new HttpContext(new HttpRequest(null, "http://tempuri.org", null), new HttpResponse(null));
  YourControllerToBeTestedController = GetYourToBeTestedController();
}
Question

I'm trying to add unit testing to an ASP.NET MVC application I have built. In my unit tests I use the following code:

[TestMethod]
public void IndexAction_Should_Return_View() {
    var controller = new MembershipController();
    controller.SetFakeControllerContext("TestUser");

    ...
}

With the following helpers to mock the controller context:

public static class FakeControllerContext {
    public static HttpContextBase FakeHttpContext(string username) {
        var context = new Mock<HttpContextBase>();

        context.SetupGet(ctx => ctx.Request.IsAuthenticated).Returns(!string.IsNullOrEmpty(username));

        if (!string.IsNullOrEmpty(username))
            context.SetupGet(ctx => ctx.User.Identity).Returns(FakeIdentity.CreateIdentity(username));

        return context.Object;
    }

    public static void SetFakeControllerContext(this Controller controller, string username = null) {
        var httpContext = FakeHttpContext(username);
        var context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);
        controller.ControllerContext = context;
    }
}

This test class inherits from a base class which has the following:

[TestInitialize]
public void Init() {
    ...
}

Inside this method it calls a library (which i have no control over) which tries to run the following code:

HttpContext.Current.User.Identity.IsAuthenticated

Now you can probably see the problem. I have set the fake HttpContext against the controller but not in this base Init method. Unit testing / mocking is very new to me so I want to make sure I get this right. What is the correct way for me to Mock out the HttpContext so that it is shared across my controller and any libraries which are called in my Init method.




If your application third party redirect internally, so it is better to mock HttpContext in below way :

HttpWorkerRequest initWorkerRequest = new SimpleWorkerRequest("","","","",new StringWriter(CultureInfo.InvariantCulture));
System.Web.HttpContext.Current = new HttpContext(initWorkerRequest);
System.Web.HttpContext.Current.Request.Browser = new HttpBrowserCapabilities();
System.Web.HttpContext.Current.Request.Browser.Capabilities = new Dictionary<string, string> { { "requiresPostRedirectionHandling", "false" } };