Модульное тестирование загрузки файла, как? - PullRequest
15 голосов
/ 29 ноября 2011

Использование MVC3.NET У меня есть метод загрузки файлов в контроллер, который отлично работает со следующей подписью public ActionResult UploadFile(IEnumerable<HttpPostedFileBase> file)

Как я могу протестировать это с NUnit? Я посмотрел вокруг, и все, кажется, указывают на Moq, но я новичок в модульном тестировании и не могу заставить Moq работать.

Я нашел интересные блоги, такие как этот: http://danielglyde.blogspot.com/2011/07/tdd-with-aspnet-mvc-3-moq-and.html, но я изо всех сил пытаюсь выяснить, как можно сделать то же самое, чтобы «подделать» загрузку файла, и также опасаюсь, что на примерах Moq, которые я удалось найти теперь, кажется, устарел код в них.

Я просто хотел бы знать, как я могу имитировать HttpPostedFileBase, чтобы я мог проверить свой код загрузки, используя Moq или иным способом - я был бы очень признателен, если бы кто-то мог дать мне несколько примеров кода о том, как это сделать.

Следующий код взят из других примеров здесь:

var file = new Mock<HttpPostedFileBase>();
            file.Setup(f => f.ContentLength).Returns(1);
            file.Setup(f => f.FileName).Returns("test.txt");

controller.upload(file);

генерирует следующую ошибку при попытке компиляции:

не может конвертировать из 'Moq.Mock' в 'System.Web.HttpPostedFileBase'

На данный момент я изменил метод для получения единственного HttpPostedFileBase, а не IEnumerable, так как для целей этого вопроса я пытаюсь сосредоточиться на том, чтобы «высмеивать» один из них.

1 Ответ

24 голосов
/ 29 ноября 2011

При условии стандартного действия загрузки файла:

[HttpPost]
public ActionResult UploadFile(IEnumerable<HttpPostedFileBase> files)
{
    foreach (var file in files)
    {
        var filename = Path.Combine(Server.MapPath("~/app_data"), file.FileName);
        file.SaveAs(filename);
    }
    return View();
}

Вы можете проверить это так:

[Test]
public void Upload_Action_Should_Store_Files_In_The_App_Data_Folder()
{
    // arrange
    var httpContextMock = new Mock<HttpContextBase>();
    var serverMock = new Mock<HttpServerUtilityBase>();
    serverMock.Setup(x => x.MapPath("~/app_data")).Returns(@"c:\work\app_data");
    httpContextMock.Setup(x => x.Server).Returns(serverMock.Object);
    var sut = new HomeController();
    sut.ControllerContext = new ControllerContext(httpContextMock.Object, new RouteData(), sut);

    var file1Mock = new Mock<HttpPostedFileBase>();
    file1Mock.Setup(x => x.FileName).Returns("file1.pdf");
    var file2Mock = new Mock<HttpPostedFileBase>();
    file2Mock.Setup(x => x.FileName).Returns("file2.doc");
    var files = new[] { file1Mock.Object, file2Mock.Object };

    // act
    var actual = sut.UploadFile(files);

    // assert
    file1Mock.Verify(x => x.SaveAs(@"c:\work\app_data\file1.pdf"));
    file2Mock.Verify(x => x.SaveAs(@"c:\work\app_data\file2.doc"));
}

Очевидно, что вся часть настройки HttpContext должна быть переведена в класс для повторного использования , который можно вызвать на этапе [SetUp] вашего юнит-теста, чтобы подготовить фиктивный контекст тестируемого объекта и избежать повторения это в каждом модульном тесте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...