是否有可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了 。
- ASP.NET Web API – 请求特定的全局变量
- ASP.NET web api无法获得application / x-www-form-urlencoded HTTP POST
- 元数据与WebAPi OData属性路由不起作用
- 你能在控制器中使用generics方法吗?
- 同时阅读FromUri和FromBody
- ASP.NET Web API中的多个PUT方法
- Castle Windsor ApiController工厂实现ASP.NET Web API
- 使用x-www-form-urlencoded发布数据的ASP.Net Web API自定义模型绑定 – 似乎没什么用
- Unity.WebApi | 确保控制器具有无参数的公共构造函数