Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock HttpContext for unit testing a .NET core MVC controller?

People also ask

Can we mock HttpContext?

Fortunately, HttpContext itself is fakeable just enough for you do replace the IPrincipal (User) and IIdentity . @CiaranG - MVC uses HttpContextBase , which can be mocked. There's no need to use the workaround I posted if you are using MVC.

How use HttpContext current in .NET core?

ASP.NET Core apps access HttpContext through the IHttpContextAccessor interface and its default implementation HttpContextAccessor. It's only necessary to use IHttpContextAccessor when you need access to the HttpContext inside a service.


I was able to initialize the httpcontext and header in this way:

[TestMethod]
public void TestValuesController()
{
    ValuesController controller = new ValuesController();
    controller.ControllerContext = new ControllerContext();
    controller.ControllerContext.HttpContext = new DefaultHttpContext();
    controller.ControllerContext.HttpContext.Request.Headers["device-id"] = "20317";
    var result = controller.Get();
    //the controller correctly receives the http header key value pair device-id:20317
    ...
}

Rather than mocking out the HTTPContext, it is probably a better idea to map the header into a parameter on the method. For example, in the controller at the bottom of this answer, the id parameter is set to the value header with a name equal to "device-id"... The unit test then becomes

[TestMethod]
public void TestValuesController()
{
    ValuesController controller = new ValuesController();
    var result = controller.GetHeaderValue("27");
    Assert.AreEqual(result, "27");
}

While you can mock the HttpContext, in my opinion it is something that should be avoided unless you have no choice. The documentation for the FromHeaderAttribute can be found here FromHeaderAttribute Class.

public class ValuesController: Controller
{
    public string GetHeaderValue([FromHeader(Name = "device-id")] string id)
    {
        return id;
    }
}