Использование Request.Files.Count с TestControllerBuilder от MvcContrib? - PullRequest
1 голос
/ 30 июля 2009

У меня есть действие контроллера в ASP.NET MVC, которое обрабатывает загруженные файлы. Тем не менее, кажется, что нет способа вызвать Request.Files.Count при использовании MvcContrib's TestControllerBuilder.

Я знаю, что могу обойти это путем абстрагирования Request.Files. Мои вопросы:

  1. Действительно ли так, что прямого вызова Request.Files.Count при использовании TestControllerBuilder не существует? Или я что-то не так делаю?
  2. Есть ли способ заглушить вызов на Request.Files.Count при использовании TestControllerBuilder с использованием Rhino Mocks?
  3. Как вы думаете, мне следует отправить запрос или исправление для обработки Request.Files.Count в MvcContrib?

Пример кода:

Я хочу убедиться, что в коллекции Request.Files есть хотя бы один файл, поэтому в моем действии есть следующее условие:

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();
    }
}

Я использую TestControllerBuilder от MvcContrib для создания двойного теста для тестов моего контроллера. Однако вызов Request.Files.Count всегда, кажется, вызывает исключение. Например, выполнение следующего теста NUnit выдает NotImplementedException во время вызова controller.Upload() при вызове Request.Files.Count:

[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);

Спасибо

Ответы [ 2 ]

1 голос
/ 27 января 2010

I отправил исправление на Github для MvcContrib, но изменения очень просты, проблема в том, что HttpFileCollectionBase не реализует методы Count () и методы [index index], поэтому они должны быть переопределяется набором WriteableHttpFileCollection в MvcContrib.

Я вставляю сюда код для полноты, который должен быть добавлен в класс WriteableHttpFileCollection:

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

public override int Count
{
    get { return files.Count; }
}
0 голосов
/ 07 октября 2009

Я использовал этот подход для решения проблемы.

Настройка теста: string fileName = "Test 1.pdf"; FileStream stream = File.OpenRead ("log4net.config"); 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...
            }
        }
...