我正在使用新的ASP.NET WebAPI的项目中工作。我目前的任务是接受上传的文件。到目前为止,我已经使用TDD来驱逐WebAPI代码,但我已经上传了一个墙。我目前正在遵循http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-2中的建议,但似乎根本无法将其推出单元测试。为了获取文件和表单数据,我必须使用MultipartFormDataStreamProvider
,这是不可能模拟和/或覆盖的。如果没有放弃我的TDD方法,我该怎么办?
以下是示例中的代码:
public Task<HttpResponseMessage> 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<HttpResponseMessage>(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);
对于初学者来说,为了对这段代码进行单元测试,我需要能够注入这样的提供者。在那个简单的构造函数调用中,它在“新增它”中排除了太多。还有另一种方式。 (如果没有,WebAPI失败)
答案 0 :(得分:3)
我抽象出了一个提供程序包装器,所以我可以模拟那些移动部件,比如
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 };
不理想,但给出了一些想法。你觉得怎么样?
答案 1 :(得分:2)
如果您使用self-hosting功能,则可以编写单元测试:
AddFile
函数执行此操作)答案 2 :(得分:2)
如果您还没有在Web API上放弃,您可以尝试System.Net.Http.TestableMultipartStreamProviders,这是Microsoft流提供程序的简单重写。它们的好处是它们依赖SystemWrapper进行文件操作,这意味着可以在单元测试中模拟文件操作。 wiki提供了一些关于利用DI来使测试控制器不那么痛苦的想法。
答案 3 :(得分:-1)
答案是“不”。 ASP.NET是一个基于继承的框架。如果您正在尝试编写基于组合的应用程序,那么您将在某个时刻找到摩擦和路障。是时候切换到Nancy。
了