0

I have a .NET C# Web API application. I have a single url controller endpoint which receives a POST message. When I run the app and I use an external tool to send the POST message it works perfectly fine.

However, when I trigger the controller from my unit test I get a null ref. exception because for some reason HttpContext.Current is null

This is my current controller (which works in a real scenario):

    [HttpPost]
    public async Task<IHttpActionResult> Post()
    {
            await Request.Content.ReadAsStringAsync();

            if (Request.Content.IsFormData())
            {
                var stuff = HttpContext.Current.Request["stuff"];
            }

            return Ok();
        }
    }

This is my unit test file:

[TestFixture]
public class AnnotationsControllerTest : BaseIntegrationTest
{
    private const string Uri = "http://localhost:2622/api/annotations";

    [Test]
    public async void TestHistoriesPost()
    {
        var form = new List<KeyValuePair<string, string>>();
        form.Add(new KeyValuePair<string, string>("stuff", "123456"));

        using (var request = new HttpRequestMessage(HttpMethod.Post, Uri))
        using (var config = new HttpConfiguration())
        {
            var route = config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}");
            using (var content = new FormUrlEncodedContent(form))
            {
                request.Content = content;
                var mockDataService = GetDataServices();
                var controller = new AnnotationsController(mockDataService.Object, ApiTestConfiguration());
                SetupController(route, controller, config, request);

                var actionResult = await controller.Post();
                var httpResponseMessage = await actionResult.ExecuteAsync(CancellationToken.None);
                Assert.AreEqual(HttpStatusCode.OK, httpResponseMessage.StatusCode);
            }
        }
    }

    private static void SetupController(
        IHttpRoute route,
        ApiController controller,
        HttpConfiguration configuration,
        HttpRequestMessage request)
    {
        var routeData = new HttpRouteData(route, new HttpRouteValueDictionary { { "controller", "Annotations" } });
        controller.ControllerContext = new HttpControllerContext(configuration, routeData, request);
        configuration.Services.Replace(typeof(IExceptionHandler), new UnhandledExceptionHandler());
        controller.Request = request;
        controller.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = configuration;
    }

    private Mock<IDataServices> GetDataServices()
    {
        return new Mock<IDataServices>();
    }
}
Gianluca Ghettini
  • 9,354
  • 14
  • 63
  • 132
  • Would are trying to do won't work. Please see: http://stackoverflow.com/questions/31189028/testing-a-web-api-method-that-uses-httpcontext-current-request-files or this here as a workaround: http://stackoverflow.com/questions/4379450/mock-httpcontext-current-in-test-init-method – Krumelur Sep 21 '16 at 08:43
  • You can make your `HttpContext` like `HttpContext.Current = new HttpContext(new HttpRequest(null, "http://tempuri.org", null), new HttpResponse(null));`. – Alessandro D'Andria Sep 21 '16 at 08:50
  • 1
    `for some reason HttpContext.Current is null` - the reason is because your unit test does not run inside ASP.NET. – Stephen Cleary Sep 21 '16 at 13:59
  • thank you all. I managed to solve the problem – Gianluca Ghettini Sep 21 '16 at 14:00

0 Answers0