Передача Mocked HttpPostedFileBase в качестве параметра контроллера MVC 3 - PullRequest
3 голосов
/ 21 февраля 2012

У меня есть проблема Mock - я использую MVC 3 с платформой nunit и пытаюсь смоделировать контроллер, имеющий HttpPostedFileBase в качестве параметра. Подпись контроллера выглядит так:

 public ActionResult UploadAttachment(AttachmentViewModel clientAttachment, HttpPostedFileBase file, string clientName)

Я установил ссылку Mock для моего параметра "file", но он жалуется, что не будет принимать Mock Object. Я предполагаю, что мне нужно настроить ControllerContext для этого сценария, но мне тоже не повезло с этим. Для первого теста мне просто нужен HttpPostedFileBase для возврата пустого файла (в случае, если в него попадает пустая ссылка на файл). Я также прочитал отличную статью Скотта Хансельмана на эту тему ( компьютер Zen ). Кажется, что ключевое предложение в разделе MVC для меня состоит в том, что «вы получите динамически сгенерированный производный макет HttpRequestBase при работе вне веб-сервера (как внутри теста), когда вы создадите свой собственный ControllerContext». Кажется, это то, где я врезаюсь в стены.

Я знаю, что мне нужны эти элементы:

controller.ControllerContext = new ControllerContext(mockContext.Object, new RouteData(), controller);
mockContext.SetupGet(c => c.Request).Returns(mockRequest.Object);
mockRequest.Setup(c => c.HttpMethod).Returns([not sure what to evoke here]);

Я нахожусь в состоянии застрять. Спасибо за любые советы или подталкивания в правильном направлении.

1 Ответ

7 голосов
/ 21 февраля 2012

Предполагается, что вы используете реальную модель представления (которая используется вашим действием контроллера, а не набором параметров):

public class MyViewModel
{
    public HttpPostedFileBase File { get; set; }

    // those won't be used in my example but you get the point
    public string ClientName { get; set; }
    public AttachmentViewModel ClientAttachment { get; set; }
}

и контроллер с действием, которое вы пытаетесь выполнить модульным тестом.:

public class HomeController : Controller
{
    [HttpPost]
    public ActionResult UploadAttachment(MyViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        var file = Path.Combine(Server.MapPath("~/App_Data"), model.File.FileName);
        model.File.SaveAs(file);
        return RedirectToAction("succes");
    }
}

теперь у вас есть 2 случая для покрытия:

  • неверное состояние модели => возвращено представление
  • действительное состояние модели => файл сохранен имы перенаправили.

Давайте начнем:

[TestMethod]
public void UploadAttachment_Should_Return_View_If_ModelState_Is_Not_Valid()
{
    // arrange
    var sut = new HomeController();
    var model = new MyViewModel();
    sut.ModelState.AddModelError("file", "please select a file");

    // act
    var actual = sut.UploadAttachment(model);

    // assert
    Assert.IsInstanceOfType(actual, typeof(ViewResult));
}

и второй случай курса:

[TestMethod]
public void UploadAttachment_Should_Save_File_If_Model_Is_Valid_And_Redirect()
{
    // arrange
    var sut = new HomeController();
    var file = new Mock<HttpPostedFileBase>();
    file.Setup(x => x.FileName).Returns("foo.txt");
    var model = new MyViewModel
    {
        File = file.Object
    };
    var server = new Mock<HttpServerUtilityBase>();
    server.Setup(x => x.MapPath("~/App_Data")).Returns(@"c:\wwwroot\App_Data");
    var httpContext = new Mock<HttpContextBase>();
    httpContext.Setup(x => x.Server).Returns(server.Object);
    sut.ControllerContext = new ControllerContext(httpContext.Object, new RouteData(), sut);

    // act
    var actual = sut.UploadAttachment(model);

    // assert
    Assert.IsInstanceOfType(actual, typeof(RedirectToRouteResult));
    file.Verify(x => x.SaveAs(@"c:\wwwroot\App_Data\foo.txt"));
}

Надеюсь, что это выведет вас на правильный путь.Извините, он использует MSTest вместо NUnit, но порт должен быть более чем тривиальным (не должен занимать у вас более 30 человеко-секунд работы).Замените [TestMethod] на [Test], и вы не должны быть далеко от цели.И да, я держу пари, 2 * что у этого Assert.IsInstanceOfType есть эквивалент в NUnit.

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