5

I want to test my MVC application, and I want to mock HttpContext. I'm using Moq framework, and here is what I've done to mock HttpContext:

[SetUp]
public void Setup()
{
    MyUser myUser = new MyUser();
    myUser.Id = 1;
    myUser.Name = "AutomatedUITestUser";

    var fakeHttpSessionState = 
                         new FakeHttpSessionState(new SessionStateItemCollection());
    fakeHttpSessionState.Add("__CurrentUser__", myUser);

    ControllerContext mockControllerContext = Mock.Of<ControllerContext>(ctx =>
        ctx.HttpContext.User.Identity.Name == myUser.Name &&
        ctx.HttpContext.User.Identity.IsAuthenticated == true &&
        ctx.HttpContext.Session == fakeHttpSessionState &&
        ctx.HttpContext.Request.AcceptTypes == 
                       new string[]{ "MyFormsAuthentication" } &&
        ctx.HttpContext.Request.IsAuthenticated == true &&
        ctx.HttpContext.Request.Url == new Uri("http://moqthis.com") &&
        ctx.HttpContext.Response.ContentType == "application/xml");

    _controller = new SomeController();
     _controller.ControllerContext = mockControllerContext; //this line is not working
    //when I see _controller.ControllerContext in watch, it get's me 
    //_controller.ControllerContext threw an exception of type System.ArgumentException
}

[Test]
public void Test_ControllerCanDoSomething()
{
    // testing an action of the controller
    // The problem is, here, System.Web.HttpContext.Current is null
}

Because my application uses Session to hold user data and authentication info in almost every action method, thus I need to set HttpContext and inside it I need to set Session and put __CurrentUser__ inside session, so that action methods would have access to faked logged in user.

However, HttpContext is not set and it's null. I've searched a lot and I couldn't find my answer. What might be wrong?

Update: I also test below line, and get same result

_controller.ControllerContext = new ControllerContext(
                       mockControllerContext.HttpContext, new RouteData(), _controller);
Omid Shariati
  • 1,904
  • 5
  • 22
  • 44
  • possible duplicate of [How do I mock the HttpContext in ASP.NET MVC using Moq?](http://stackoverflow.com/questions/1452418/how-do-i-mock-the-httpcontext-in-asp-net-mvc-using-moq) – Mike Cheel Mar 05 '14 at 15:26
  • Microsoft recommends using HttpContextWrapper in your code so that unit testing will be easier later on.http://msdn.microsoft.com/en-us/library/system.web.httpcontextwrapper(v=vs.110).aspx – Mike Cheel Mar 05 '14 at 15:27
  • thanks @MikeCheel but my question is different, I dont set HttpContext instead of ControllerContext, my problem is I can't set ControllerContext ! can anyone answer my qiestion ? – Omid Shariati Mar 05 '14 at 15:43
  • You can create a ControllerContext and pass in a HttpContextBase into its constructor. Also, the HttpContext on the ControllerContext is an HttpContextBAse and so you should be able to use the HttpContextWrapper. – Mike Cheel Mar 05 '14 at 15:57
  • I also test below line, and get same result _controller.ControllerContext = new ControllerContext(mockControllerContext.HttpContext, new RouteData(), _controller); – Omid Shariati Mar 05 '14 at 16:11
  • Have you tried enabling .net source code stepping in visual studio to see where the exception is thrown it might give you some more hints? – Alex KeySmith Mar 06 '14 at 10:13

1 Answers1

3

Judging by this answer: Mocking Asp.net-mvc Controller Context

It looks like you need to mock the Request itself, as well as the properties of the request object.

e.g.

var request = new Mock<HttpRequestBase>();

etc (the full code is in the linked answer).

Community
  • 1
  • 1
Alex KeySmith
  • 16,657
  • 11
  • 74
  • 152