How to setup Request.Header in FakeHttpContext for Unit Testing

20,006

Solution 1

I just discovered that with HttpRequestMessage class, you can easily add headers for testing your WebAPI controllers without having to create any fake HttpContext.

var request = new HttpRequestMessage(HttpMethod.Get, "http://stackoverflow");
request.Headers.Add("deviceId","1234");
_myController.Request = request;

Solution 2

I'm using .Net Core 3.1 and the Moq framework. I created a DefaultHttpContext, set the headers there, finally assigned it to the controller ControllerContext constructor.

var httpContext = new DefaultHttpContext();
httpContext.Request.Headers["X-Example"] = "test-header";
var controller = new ExampleController(mockClient.Object, mockLogger.Object) 
{ 
    ControllerContext = new ControllerContext()
    {
        HttpContext = httpContext
    }
};

Source: https://www.thecodebuzz.com/unit-test-mock-httprequest-in-asp-net-core-controller/

Share:
20,006
Oluwafemi
Author by

Oluwafemi

If I am not writing code, I am spending time with my family. Tech Lead, Family Man, Church boy Website: https://www.codewithfemi.com/ Please watch and Subscribe to my YouTube channel: https://www.youtube.com/c/codewithfemi Console.WriteLine("Life is simple with Christ Jesus");

Updated on November 11, 2020

Comments

  • Oluwafemi
    Oluwafemi over 3 years

    I have a FakeHttpContext I have been trying to modify to include some headers for testing purposes

    public static HttpContext FakeHttpContext()
    {
        var httpRequest = new HttpRequest("", "http://stackoverflow/", "");
        var stringWriter = new StringWriter();
        var httpResponse = new HttpResponse(stringWriter);
        var httpContext = new HttpContext(httpRequest, httpResponse);   
    
        var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(),
                                                        new HttpStaticObjectsCollection(), 10, true,
                                                        HttpCookieMode.AutoDetect,
                                                        SessionStateMode.InProc, false);
    
        httpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor(
                                            BindingFlags.NonPublic | BindingFlags.Instance,
                                            null, CallingConventions.Standard,
                                            new[] { typeof(HttpSessionStateContainer) },
                                            null)
                                    .Invoke(new object[] { sessionContainer });
    
        return httpContext;
     }
    

    This works without the headers but when I add any of these lines of code in between the httpRequest and stringWriter lines.

        httpRequest.Headers.Add("blah", "1234");
        httpRequest.Headers["blah"] = "1234";
    

    It throws

    An exception of type 'System.PlatformNotSupportedException' occurred in System.Web.dll but was not handled in user code

    • Why am I getting that exception?
    • Is there a possible way to add headers to HttpContext for testing WebApi controllers?
    • Reddog
      Reddog almost 9 years
      If you can get your code to work with HttpContextBase, then you can usually mock things like this (including the request, and the request headers). Generally, that shouldn't be a problem as long as you aren't using HttpContext.Current.
    • Oluwafemi
      Oluwafemi almost 9 years
      I tried following the answers on this link stackoverflow.com/questions/32640/… but it seems not to work with WebAPI controllers but MVC controllers
  • Oliver Pearmain
    Oliver Pearmain almost 4 years
    Property or indexer 'ControllerBase.Request' cannot be assigned to -- it is read only :-(
  • John Irvine
    John Irvine almost 3 years
    This one worked great for me, Controller.Request was readonly (.net cor 5) not sure if I missed something.
  • ayush mishra
    ayush mishra over 2 years
    please provide the code for the setup of DefaultHttpContext class
  • ayush mishra
    ayush mishra over 2 years
    Doesn't work in my case
  • m4verick
    m4verick over 2 years
    It works like a charm ! thaks @DMendonza
  • DMendoza
    DMendoza over 2 years
    @ayushmishra The DefaultHttpContext class is part of the Microsoft.AspNetCore.Http namespace. Here's the link to Microsoft's documentation on it: DefaultHttpContext Class