Модульное тестирование (xUnit) контроллера ASP.NET Mvc с настраиваемой моделью ввода?

Мне трудно найти информацию о том, что, как я ожидаю, будет довольно простым сценарием. Я пытаюсь выполнить модульное тестирование Action на моем контроллере ASP.NET Mvc 2, который использует пользовательскую модель ввода с DataAnnotions. Моя среда тестирования — xUnit, как указано в заголовке.

Вот моя пользовательская модель ввода:

public class EnterPasswordInputModel
{
    [Required(ErrorMessage = "")]
    public string Username { get; set; }

    [Required(ErrorMessage = "Password is a required field.")]
    public string Password { get; set; }
}

А вот мой Контроллер (убрал немного логики для упрощения примера):

[HttpPost]
public ActionResult EnterPassword(EnterPasswordInputModel enterPasswordInput)
{
    if (!ModelState.IsValid)
        return View();

    // do some logic to validate input
    // if valid - next View on successful validation
        return View("NextViewName");
    // else - add and display error on current view
        return View();
}

А вот мой xUnit Fact (тоже упрощенный):

[Fact]
public void EnterPassword_WithValidInput_ReturnsNextView()
{
    // Arrange
    var controller = CreateLoginController(userService.Object);

    // Act
    var result = controller.EnterPassword(
        new EnterPasswordInputModel
            {
                Username = username, Password = password
            }) as ViewResult;

    // Assert
    Assert.Equal("NextViewName", result.ViewName);
}

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

System.NullReferenceException: Object reference not set to an instance of an object.

Заранее спасибо за любую помощь, которую вы можете предложить!


person Danny Douglass    schedule 14.05.2010    source источник
comment
Когда вы отлаживаете, что является нулевым? Состояние модели?   -  person Jab    schedule 14.05.2010


Ответы (2)


Я думаю, что я на пути к решению, хотя. Вот изменения, которые я внес в свой контроллер:

Исходный

if (!ModelState.IsValid)
    return View();

Обновлено

if (!TryUpdateModel(loginInput))
            return View();

Кажется, что привязка модели не происходила во время моего теста. Похоже, что привязка модели не происходит, если не происходит POST. Принудительно пытаясь привязать модель, я смог пройти тест.

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

Ссылка: http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html

person Danny Douglass    schedule 14.05.2010
comment
упс - для примера с переполнением стека мое обновление должно было использовать enterPasswordInput, а не loginInput. Последний используется в моем реальном коде. =П - person Danny Douglass; 14.05.2010

Вы разыменовываете нулевой экземпляр внутри действия вашего контроллера. Вероятно, в коде, который вы вынули, чтобы «упростить» вопрос. Посмотрите на стек вызовов в результатах теста, чтобы понять, что именно. Возможно, вам нужно что-то смоделировать для теста.

person Craig Stuntz    schedule 14.05.2010
comment
Smack на мою первоначальную ошибку! Настоящая проблема заключалась в том, что моя модель не проверялась с использованием ModelState.IsValid в действии контроллера. Мой ответ ниже расширяет это... - person Danny Douglass; 14.05.2010