質問

ASP.NET MVCには、アップロードされたファイルを処理するコントローラーアクションがあります。ただし、MvcContribの TestControllerBuilder を使用中に Request.Files.Count を呼び出す方法はないようです。

Request.Files を抽象化することでこの問題を回避できることを知っています。私の質問は:

  1. 実際には、 TestControllerBuilder を使用するときに Request.Files.Count を呼び出す直接的な方法はないのですか?それとも私は何か間違っているのですか?
  2. Rhino Mocksを使用して TestControllerBuilder を使用しながら、 Request.Files.Count への呼び出しをスタブする方法はありますか?
  3. Request.Files.Count を処理するためのリクエストまたはパッチをMvcContribに送信する必要があると思いますか?

サンプルコード:

Request.Files コレクションに少なくとも1つのファイルがあることを確認したいので、アクションに次の条件があります:

public class MyController : Controller {
    public ActionResult Upload() {
        if (Request.Files == null || Request.Files.Count == 0)
            ViewData.ModelState.AddModelError("File", "Please upload a file");
        // do stuff
        return View();
    }
}

MvcContribの TestControllerBuilder を使用して、コントローラーテスト用のテストダブルを作成しています。ただし、 Request.Files.Count の呼び出しは常に例外をスローするようです。たとえば、次のNUnitテストを実行すると、 Request.Files.Count への呼び出しで controller.Upload()への呼び出し中に NotImplementedException がスローされます。

[Test]
public void Upload_should_return_default_view_given_one_file() {
    MyController controller = new MyController();
    TestControllerBuilder controllerBuilder = new TestControllerBuilder();
    controllerBuilder.InitializeController(controller);
    controllerBuilder.Files["file"] = 
        MockRepository.GenerateStub<HttpPostedFileBase>();

    var result = controller.Upload() as ViewResult;

    Assert.That(result.ViewData.ModelState.IsValid, Is.True);
    result.AssertViewRendered().ForView(string.Empty);
}

また、 Request.Files.Count への呼び出しをスタブ化して無駄にしました(Rhino Mocksを使用しています)。以下のいずれも機能しません( controller controllerBuilder をスタブに変更しても):

controllerBuilder.Stub(cb => cb.HttpContext.Request.Files.Count).Return(1);
controller.Stub(c => c.Request.Files.Count).Return(1);

ありがとう

役に立ちましたか?

解決

I パッチをGithubでMvcContrib mantainersに送信したが、変更は非常に大きい簡単に作成できますが、問題はHttpFileCollectionBaseがCount()およびthis [int index]メソッドを実装していないため、MvcContribのWriteableHttpFileCollectionでオーバーライドする必要があることです。

完全を期すため、ここにコードを貼り付けます。WriteableHttpFileCollectionクラスに追加する必要があります。

public override HttpPostedFileBase this[int index]
{
    get { return files[AllKeys[index]]; }
}

public override int Count
{
    get { return files.Count; }
}

他のヒント

このアプローチを使用して問題を解決しました。

テストのセットアップ:             string fileName =&quot; Test 1.pdf&quot ;;             FileStream stream = File.OpenRead(&quot; log4net.config&quot;);             MockRepository mock = new MockRepository();

        builder.Files[fileName] = mock.CreateMock<HttpPostedFileBase>();
        using (mock.Record())
        {
            Expect.Call(builder.Files[fileName].FileName)
                  .Return(fileName);
            Expect.Call(builder.Files[fileName].ContentType)
                  .Return(contentType);
            Expect.Call(builder.Files[fileName].ContentLength)
                  .Return(Convert.ToInt32(stream.Length.ToString()));
            Expect.Call(builder.Files[fileName].InputStream)
                  .Return(stream);
        }

モックの使用:

        foreach(string key in Request.Files.AllKeys)
        {
            int lenght = Request.Files[key].ContentLength;
            if (lenght > 0)
            {
                Document document = new Document();
                string fileName = Request.Files[key].FileName;
                byte[] content= new byte[Convert.ToInt32(lenght)];
                Request.Files[key].InputStream.Read(content, 0, content.Length);
                document.SetContent(content);
                document.MimeType = Request.Files[key].ContentType;
                // do whatever you want...
            }
        }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top