2

I have browsed through various posts and tried several things but I haven't been able to get things working right. I dont feel it should be that hard, but here's what I got. I simply want to post a file to my server for testing purposes. It should work as if i was uploading it from a standard <input type="file"/> on a web page.

This is the actual handler I want to test:

[Route("MyAction")]
[HttpPost]
public IHttpActionResult MyAction()
{
    try
    {
        var request = HttpContext.Current.Request;
        if (request.Files.Count == 1)
        {
            var postedFile = request.Files[0];
            if (request.Files[0].FileName.EndsWith(".zip"))
            {
                // unzip the file
                // do stuff
            }
        }
    }
    catch 
    {
        return new ValidationError("An error has occurred and has been logged");
    }
}

This is my test:

public void SetupServer()
{
    server = TestServer.Create(app =>
    {
        var startup = new Startup();
        startup.ConfigureOAuth(app);

        var config = new HttpConfiguration();
        WebApiConfig.Register(config);

        app.UseWebApi(config);
    });
}


[Test]
public async Task MyActionTest()
{
    SetupServer();
    Uri = "/api/myClass/myRoute";

    var file = Properties.Resources.myZipFile;

    var boundary = "------------------------" + DateTime.Now.Ticks;

    var multipartFileContent = new MultipartFormDataContent(boundary);
    var content = new ByteArrayContent(file);
    content.Headers.Add("Content-Type", "application/octet-stream");
    multipartFileContent.Add(content, "myFileName", "myZipFile.zip");

    var serverResp = (await server.CreateRequest(Uri)
        .And(req => req.Content = multipartFileContent)
        .PostAsync());
}

Running this test causes an error on var request = HttpContext.Current.Request; because HttpContext.Current is null for some reason. Am I going about this in a wrong or hard way? I feel it shouldn't be this difficult.

jensengar
  • 6,117
  • 17
  • 58
  • 90

2 Answers2

5

The issue is that HttpContext.Current isn't available in the self-hosted test you're spinning up.

Take a look here:

HttpSelfHostServer and HttpContext.Current

Community
  • 1
  • 1
Veatch
  • 893
  • 7
  • 11
2

The root problem is to do with how the HttpContext.Current works. This property is "magical" in the ASP.NET framework, in that it is unique for a request-response operation, but jumps between threads as the execution requires it to - it is selectively shared between threads.

When you use HttpContext.Current outside of the ASP.NET processing pipeline, the magic goes away. When you switch threads like you are here with the asynchronous programming style, the property is null after continuing. http://www.necronet.org/archive/2010/07/28/unit-testing-code-that-uses-httpcontext-current-session.aspx

Kashif
  • 2,926
  • 4
  • 20
  • 20