Ответ 1
Ответ "нет". ASP.NET - это основанная на наследовании структура. Если вы пытаетесь написать композиционные приложения, вы в какой-то момент найдете трение и дорожные блоки. Время переключиться на что-то вроде Nancy.
Я работаю над проектом, который использует новый ASPAP WebAPI. Моя текущая задача - принять загруженный файл. До сих пор я использовал TDD для извлечения кода WebAPI, но я ударил стену с загрузкой. В настоящее время я следую рекомендациям, изложенным в http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-2, но, похоже, нет никакого способа выгнать это из unit test. Чтобы получить данные о файле и форме, я должен использовать 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);
Для начала, до unit test этого кода, мне нужно иметь возможность ввести такого провайдера. Это слишком сложно в этом простом вызове конструктора, чтобы "обновить его" в строке. Должен быть другой путь. (Если нет, произойдет сбой WebAPI)
Ответ "нет". ASP.NET - это основанная на наследовании структура. Если вы пытаетесь написать композиционные приложения, вы в какой-то момент найдете трение и дорожные блоки. Время переключиться на что-то вроде Nancy.
Если вы используете возможность самостоятельного хостинга, вы можете написать unit test, который:
AddFile
, чтобы сделать это)Я отвлек оболочку провайдера, чтобы я мог издеваться над этими движущимися частями, что-то вроде
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 };
Не идеален, но дает некоторое умение. Как вы думаете?
Если вы еще не загрузили полотенце в веб-API, вы можете попробовать System.Net.Http.TestableMultipartStreamProviders, которые являются выпадающую переписку с поставщиками потоков Microsoft. Их преимуществом является то, что они полагаются на SystemWrapper для операций с файлами, что означает, что операции с файлами можно издеваться над модульными тестами. wiki дает некоторые идеи об использовании DI, чтобы сделать контрольные контролеры менее болезненными.