C#Web API Mock HttpContext.Current.Request测试文件上传

时间:2018-01-19 00:42:10

标签: c# unit-testing asp.net-web-api file-upload

我正在尝试模拟以下控制器中测试文件上载功能的请求:

public HttpResponseMessage Upload()
{
     var httpRequest = HttpContext.Current.Request;
     if (httpRequest.Files.Count > 0 &&
        httpRequest.Params != null &&
        httpRequest.Params.GetValues("param1") != null &&
        httpRequest.Params.GetValues("param1")[0] != null &&
        httpRequest.Params.GetValues("param2") != null &&
        httpRequest.Params.GetValues("param2")[0] != null)
    {
        var postedFile = httpRequest.Files[0];
        //do something
    }
}

这是我的测试方法

[TestMethod]
public void CheckSuccessfulUpload()
{
    //arrange
    const string fileUploadXML = "<?xml version=\"1.0\" encoding =\"utf8\"?>" +
             "<employees><employee id=\"1\" name=\"A\">" +
             "<employees><employee id=\"2\" name=\"B\">" +
             "<employees><employee id=\"3\" name=\"C\">" +
             "</employees>";

    //Create the file here to upload
    //Set a variable to the My Documents path.
    string mydocpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
    File.WriteAllText(mydocpath + @"\Employees.xml", fileUploadXML);

    //Mock the Request
    HttpRequest request = new HttpRequest(mydocpath + @"\Employees.xml", "http://localhost/api/DataUpload", "param1=1&param2=2");
    HttpResponse response = new HttpResponse(new StringWriter());
    HttpContext.Current = new HttpContext(request, response);

    //action
    DataUploadController controller = new DataUploadController();
    controller.upload();
    //this is sending the parameters but not the file
}

我能够使用参数但不是文件成功命中控制器方法。尝试使用HttpRequestMessageHttpClientMultipartFormDataContent,但这些都不起作用。也无法在网上获得良好的参考。我也可以使用Mock / Moq框架。

1 个答案:

答案 0 :(得分:1)

如何编写一个真正测试控制器的集成测试呢?然后你可以跳过所有这些嘲弄的东西。

想象一下你的控制器动作看起来像这样:

[RoutePrefix("api/upload")]
public class UploadController : ApiController
{
    [HttpPost]
    [Route]
    public async Task<IHttpActionResult> Upload()
    {
        var result = await Request.Content.ReadAsMultipartAsync();

        if(result.Contents.Any())
        {
            var postedFile = await result.Contents.First().ReadAsStringAsync();

            // do something

            return Ok("File uploaded successfully");
        }

        return BadRequest("No files uploaded");
    }
}

然后您的集成测试可能如下所示:

[TestMethod]
public async Task CheckSuccessfulUpload()
{
    var baseAddress = new Uri("http://localhost:8000/");
    var config = new HttpSelfHostConfiguration(baseAddress);

    WebApiConfig.Register(config);

    var server = new HttpSelfHostServer(config);
    var client = new HttpClient(server)
    {
        BaseAddress = baseAddress
    };

    const string fileUploadXML = "<?xml version=\"1.0\" encoding =\"utf8\"?>" +
                                    "<employees><employee id=\"1\" name=\"A\">" +
                                    "<employees><employee id=\"2\" name=\"B\">" +
                                    "<employees><employee id=\"3\" name=\"C\">" +
                                    "</employees>";

    var content = new ByteArrayContent(Encoding.UTF8.GetBytes(fileUploadXML));
    content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
    content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
    {
        Name = "file",
        FileName = "Employees.xml"
    };

    var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Post, "api/upload")
    {
        Content = new MultipartFormDataContent("----Boundry") { content }
    });

    Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}

希望这会让你前进。您可以阅读有关自托管here的更多信息。

注意,这里我从控制器所在的程序集中引用WebApiConfig