是否有可unit testing的方法将文件上载到ASP.NET WebAPI?

我正在使用新的ASP.NET WebAPI的项目中工作。 我目前的任务是接受上传的文件。 到目前为止,我已经使用TDD来驱逐WebAPI代码,但我已经上传了一个墙。 我目前正在关注http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-2上的建议,但似乎没有完全可以将其从unit testing中推出。 为了获取文件和表单数据,我必须使用MultipartFormDataStreamProvider ,这是不可能模拟和/或覆盖的。 如果没有放弃我的TDD方法,我该怎么办?

这是示例中的代码:

 public Task PostFormData() { // Check if the request contains multipart/form-data. if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } string root = HttpContext.Current.Server.MapPath("~/App_Data"); var provider = new MultipartFormDataStreamProvider(root); // Read the form data and return an async task. var task = Request.Content.ReadAsMultipartAsync(provider). ContinueWith(t => { if (t.IsFaulted || t.IsCanceled) { Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception); } // This illustrates how to get the file names. foreach (MultipartFileData file in provider.FileData) { Trace.WriteLine(file.Headers.ContentDisposition.FileName); Trace.WriteLine("Server file path: " + file.LocalFileName); } return Request.CreateResponse(HttpStatusCode.OK); }); return task; } 

第一个问题是这一行:

 var provider = new MultipartFormDataStreamProvider(root); 

对于初学者来说,为了对这段代码进行unit testing,我需要能够注入这样的提供者。 在那个简单的构造函数调用中,它在“新建它”中排除了太多。 还有另一种方式。 (如果没有,WebAPI失败)

我抽象出了一个提供程序包装器,所以我可以模拟那些移动部件,比如

  public interface IMultiPartFormDataStreamProviderWrapper : IDependency { string LocalFileName { get; } MultipartFormDataStreamProvider Provider { get; } } public class MultiPartFormDataStreamProviderWrapper : IMultiPartFormDataStreamProviderWrapper { public const string UploadPath = "~/Media/Default/Vocabulary/"; private MultipartFormDataStreamProvider provider; public MultiPartFormDataStreamProviderWrapper(IHttpContextAccessor httpContextAccessor) { provider = new CustomMultipartFormDataStreamProvider(httpContextAccessor.Current().Server.MapPath(UploadPath)); } public string LocalFileName { get { return provider.FileData[0].LocalFileName; } } public MultipartFormDataStreamProvider Provider { get { return provider; } } } 

所以我可以做类似的事情

  if (Request.Content.IsMimeMultipartContent()) { return Request.Content.ReadAsMultipartAsync(provider.Provider).ContinueWith(t => { if (t.IsCanceled || t.IsFaulted) return (object)new { success = false }; 

不理想,但给出了一些想法。 你怎么看?

如果您使用自托管function,则可以编写unit testing:

  • 启动控制器(以及各种其他格式化程序/filter等)
  • 使用HttpClient(或者我个人,我会使用RestSharp )将文件提交给该控制器(使用RestSharp,您可以使用AddFile函数执行此操作)
  • 根据您的需要validation输入流(例如,通过覆盖提供程序或仅检查传递给测试控制器的值或其他内容)

如果您还没有在Web API上抛弃,您可以尝试使用System.Net.Http.TestableMultipartStreamProviders ,这是Microsoft流提供程序的简写重写。 它们的好处是它们依赖于SystemWrapper进行文件操作,这意味着可以在unit testing中模拟文件操作。 维基提供了一些关于利用DI来使测试控制器不那么痛苦的想法。

答案是不”。 ASP.NET是一个基于inheritance的框架。 如果您正在尝试编写基于组合的应用程序,那么您将在某个时刻找到摩擦和路障。 是时候改用Nancy了 。