18

新しい 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 は失敗します)

4

4 に答える 4

3

Web APIをまだ使用していない場合は、MicrosoftストリームプロバイダーのドロップインリライトであるSystem.Net.Http.TestableMultipartStreamProvidersを試してみてください。それらの利点は、ファイル操作をSystemWrapperに依存していることです。つまり、ファイル操作を単体テストでモックすることができます。wikiは、コントローラーのテストを簡単にするためにDIを活用することについてのいくつかのアイデアを提供します。

于 2012-11-12T16:41:16.807 に答える
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 };

理想的ではありませんが、心に留めておきます。どう思いますか?

于 2012-10-01T13:38:23.097 に答える
1

セルフホスティング機能を使用すると、次のような単体テストを作成できます。

  • コントローラー (およびその他のさまざまなフォーマッター/フィルターなど) を起動します。
  • HttpClient (または個人的にはRestSharpを使用します) を使用して、そのコントローラーにファイルを送信します (RestSharp を使用すると、AddFile関数を使用してこれを行うことができます)
  • 必要に応じて入力ストリームを検証します (たとえば、プロバイダーをオーバーライドするか、テスト コントローラーなどに渡される値を検査するだけです)。
于 2012-08-24T06:58:32.437 に答える
-2

答えはノーだ"。ASP.NET は継承ベースのフレームワークです。コンポジションベースのアプリケーションを作成しようとしている場合、ある時点で摩擦や障害が発生します。Nancyのようなものに切り替える時が来ました。

于 2012-09-12T19:21:13.900 に答える