How to fake session object / HttpContext for integration tests



Sometimes when we write integration tests we need to fake HttpContext to test some functionality proper way.

In one of my projects I needed a possibility to fake some session variables such as userState and maxId.

A project that is tested in this example is an ASP.NET Web API with added support for session but you can use the same approach in any ASP.NET/ MVC project.

Implementation is very simple. First, we need to create FakeHttpContext.

 

 public HttpContext FakeHttpContext(Dictionary<string, object> sessionVariables,string path)
{
    var httpRequest = new HttpRequest(string.Empty, path, string.Empty);
    var stringWriter = new StringWriter();
    var httpResponce = new HttpResponse(stringWriter);
    var httpContext = new HttpContext(httpRequest, httpResponce);
    httpContext.User = new GenericPrincipal(new GenericIdentity("username"), new string[0]);
    Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("username"), new string[0]);
    var sessionContainer = new HttpSessionStateContainer(
      "id",
      new SessionStateItemCollection(),
      new HttpStaticObjectsCollection(),
      10,
      true,
      HttpCookieMode.AutoDetect,
      SessionStateMode.InProc,
      false);

   foreach (var var in sessionVariables)
   {
      sessionContainer.Add(var.Key, var.Value);
   }

   SessionStateUtility.AddHttpSessionStateToContext(httpContext, sessionContainer);
   return httpContext;
}


 

After we have FakeHttpContext we can easily use it in any integration tests like this.

 

 [Test]
public void DeleteState_AcceptsCorrectExpandedState_DeletesState()
{
   HttpContext.Current = this.FakeHttpContext(
      new Dictionary<string, object> { { "UserExpandedState", 5 }, 
                                        { "MaxId", 1000 } },    
                                          "http://localhost:55024/api/v1/");

   string uri = "DeleteExpandedState";
   var result = Client.DeleteAsync(uri).Result;
   result.StatusCode.Should().Be(HttpStatusCode.OK);

   var state = statesRepository.GetState(5);
   state.Should().BeNull();
}

 

This is an example of integration test that tests Delete method of WebAPI.

WebAPI is this example hosted in memory for the purpose of integration testing.

If you like this article don’t forget to subscribe to this blog and make sure you don’t miss new upcoming blog posts.

 
 

  • Vien

    Good article. integration tests are gaining more importance.
    How about providing a wrapper class for session. And when the test calls an api(environment A) externally(the example in the article is internal calling) through dependency injection we could load a fake session. In real session application (environment B) we load real httpsession instead of fake.