Как мне подделать UpdateModel для ASP.Net MVC? - PullRequest
1 голос
/ 10 ноября 2009

Я пытаюсь выполнить модульное тестирование действия контроллера, использующего UpdateModel, но неправильно корректирую HttpContext. Я продолжаю получать следующее исключение:

System.InvalidOperationException: предыдущий метод 'HttpRequestBase.get_Form ();' для возврата требуется возвращаемое значение или исключение.

Чтобы высмеивать HttpContext, я использую что-то похожее на то, что Скотт написал для насмешек Rhino .

Я добавил один метод, который, как я думал, будет издеваться над 'HttpRequestBase.get_Form ();'

public static void SetupRequestForm(this HttpRequestBase request, NameValueCollection nameValueCollection)
{
    if (nameValueCollection == null)
        throw new ArgumentNullException("nameValueCollection");
    SetupResult.For(request.PathInfo).Return(string.Empty);
    SetupResult.For(request.Form).Return(nameValueCollection);
}

Вот модульный тест:

[Test]
public void Edit_GivenFormsCollection_CanPersistStyleChanges()
{
    //in memory db setup omitted ...

    var nameValueCollection = new NameValueCollection();
    InitFormCollectionWithSomeChanges(nameValueCollection, style);
    var httpContext = _mock.FakeHttpContext();
    _mock.SetFakeControllerContext(controller, httpContext);
    httpContext.Request.SetupRequestForm(nameValueCollection);

    controller.Edit(1, new FormCollection(nameValueCollection));

    var result = (ViewResult)controller.Edit(1);

    Assert.IsNotNull(result.ViewData);
    style = Style.GetStyle(1);
    AsserThatModelCorrectlyPersisted(style);

}

Тестируемое действие контроллера:

[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection collection)
{
    var campaign = Campaign.GetCampaign(id);

    if (campaign == null)
        return View("Error", ViewData["message"] = "Oops, could not find your requested campaign.");
    if (!campaign.CanEdit(User.Identity.Name))
        return View("Error", ViewData["message"] = "You are not authorized to edit this campaign style.");

    var style = campaign.GetStyle();
    //my problem child for tests.
    UpdateModel(style);

    if (!style.IsValid)
    {
        ModelState.AddModelErrors(style.GetRuleViolations());
        return View("Edit", style);
    }

    style.Save(User.Identity.Name);
    return RedirectToAction("Index", "Campaign", new { id });
}

Я приму любой ответ, который корректно изменяет мой SetupRequestForm, модульный тест или отправит пример того, как использовать помощников по тестированию в проекте MVCContrib для достижения той же цели.

1 Ответ

3 голосов
/ 10 ноября 2009

Вы не используете коллекцию FormCollection, переданную методу действия. Причина, по которой вы обычно передаете FormCollection, состоит в том, чтобы помочь в тестировании, нарушив зависимость UpdateModel от HttpConext.

Все, что вам нужно сделать, это изменить строку UpdateModel на:

UpdateModel(style, collection.ToValueProvider());

Как только вы это сделаете, вы можете забыть о настройке вашего макета HttpContext. Например. ваш тест теперь может выглядеть так:

[Test]
public void Edit_GivenFormsCollection_CanPersistStyleChanges()
{
    //Blah

    var nameValueCollection = new NameValueCollection();
    InitFormCollectionWithSomeChanges(nameValueCollection, style);
    //Removed stuff

    controller.Edit(1, new FormCollection(nameValueCollection));

    //Blah
}

HTHS,
Charles

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