Unit testing around HttpContext

While testing around web frameworks has greatly improved in recent years, but when there is a need to work with older frameworks like WebForms, the story isn’t quite as friendly. As webforms was not designed with testability or dependency injection in mind, it has a number of components that are statically accessed and can’t be overriden for testing. A central one of these is the HttpContext, which holds the current user identity and session information

Retrieving Http Context

  • Static resolution - The current HttpContext can be retrieved by using the HttpContext.Current static method. This is one of the commonly used older methods, but should be avoided as it makes testing extremely impractical.
  • Dependency injection - Some Dependency Injection frameworks provide integration with WebForms to provide dependency injection via Property Injection. ie Property Injection
  • Static Dependency resolution - For situations where property or constructor based dependency injection are not available, a globally accessible container instance can be used to resolve. ie Resolving global container

Overriding in tests

Setting Current HttpContext

While the old HttpContext class can’t be overrwitten, it does have some flexibility in testing, by setting properties and explicitly setting HttpContext.Current. This allows some things, such as the user principal to be manually set, but it is not possible to set properties like Session, so this a limited solution. This is also a bad idea for unit tests, as it is a singleton instance, and you don’t want tests interfering with each other.

Unfortunately as HttpContext.Current is a HttpContext, it is not possible to set it to a mocked instance of HttpContextBase.

Mocking HttpContextBase

Two additional classes have been made available since .net 3.5 to assist with working around the HTTPContext.

HttpContextBase - Abstract base for HttpContextWrapper. It is designed to be overridable to allow for mocking in tests. This class is also used for exposing the HttpContext in newer frameworks like MVC. The Autofac.Web library adds a registration for this class to the request lifetime scope for dependency injection.

HttpContextWrapper - Wrapper class that takes the old HttpContext as a parameter. It then exposes all the same properties as HttpContext, but inherits from HttpContextBase. It can then be used to transform from HttpContext to HttpContextBase via new HttpContextWrapper(HttpContext.Current). As manually converting to HttpBase may still rely on HttpContext.Current

Written on December 1, 2018