开发者

MVC Testing actions that rely on HTTPContext

I have a project where I need to p开发者_如何学Pythonrovide action tests. My approuch has been to ensure actions do not rely on anything they do not receive as parameters, maing use of ValueProviders and ModelBinders. As such I would pass in HTTPContextBase etc.

However, I now have an action which uses a static class that is a wrapper around HTTPContext to accesses Session and Identity. Thus it seems I have to mock out HTTPContext to test this action. Not too complicated, I guess, but it just feels wrong.

My gut feeling is that the static class should be redeveloped to be instantiated with HTTPSessionStateBase and IPrinicple and use them as internal stores. Then I could instantiate this wrapper in my action, from action parameters, making the action and the wrapper class much more testing friendly.

Would this be a recommended approuch or does anyone have any other ideas, were I would not have to change my static class to instance ?


I think that using Moq to mock a HttpContext is just the way you might want to try it out.

[TestMethod]
public void Test()
{

    var context = new Mock<HttpContextBase>();
    var request = new Mock<HttpRequestBase>();
    context.Setup(c => c.Request).Returns(request.Object);

    HomeController controller = new HomeController();

    controller.ControllerContext = new ControllerContext( context , new RouteData(), controller );

    ....
    ...........
}




Updated:
In the case if you want to mock HttpSession(as gdoron mentioned in comment). It is not really complicated since you are MOCKING something doesn't means you have to build entire, real object and all of its properties.

Suppose that your controller will

  1. Checks whether user is authenticated.
  2. Gets identity name.
  3. Gets a value from Session["key"].
  4. manipulates cookie.

The code could be like that:

[TestMethod]
public void Test()
{
    ......
    .........
    var mockedControllerContext = new Mock<ControllerContext> ();
    mockedControllerContext.SetupGet(p => p.HttpContext.Session["key"]).Returns("A value in session");
    mockedControllerContext.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);    
    mockedControllerContext.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("An identity name");
    mockedControllerContext.SetupGet(p => p.HttpContext.Response.Cookies).Returns(new HttpCookieCollection ());

    HomeController controller = new HomeController();
    controller.ControllerContext = mockedControllerContext.Object;
    .....
    ......

}


I strongly recommend using MvcContrib - testhelpers Learn how to use from CodePlex
You can download it from nuget or directly from CodePlex
Good luck!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜