Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock HttpContext (ControllerContext) in Moq framework, and have session

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);
like image 853
Omid Shariati Avatar asked Oct 21 '22 13:10

Omid Shariati


1 Answers

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).

like image 189
Alex KeySmith Avatar answered Nov 01 '22 11:11

Alex KeySmith