Подтвердить что ты не робот

Контроллер тестирования ASP MVC 3, вызывающий ModelState.IsValid, всегда возвращает true

У меня есть приложение ASP MVC 3, и в моей модели я реализовано IValidatableObject.

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

Я вижу много блогов и сообщений и ответов, которые говорят что-то вроде

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

Мой вопрос. Почему ModelState.IsValid всегда верен в unit test на контроллере?

Пример:

[Test]
public void InValidModelsAreNotAdded()
{
    var invalidModel = new MyModel() { SomeField = "some data", SomeOtherField = "" };

    var result = _controller.Submit(invalidModel);

    _repository.AssertWasNotCalled(r => r.Add(Arg.Is.Anything));

}

Код модели:


public class MyModel : IValidatableObject
{
    public string SomeField { get; set; }
    public string SomeOtherField { get; set; }

    public IEnumerable Validate(ValidationContext validationContext)
    {
        if(string.IsNullOrWhiteSpace(SomeOtherField))
        {
            yield return
                new ValidationResult("Oops invalid.", new[] {"SomeOtherField"});
        }
     }
}

AssertWasNotCalled всегда терпит неудачу в этом тесте.

Я прошел тест и заметил, что ModelState.IsValid верен для этого теста. Как будто IValidatableObject.Validate не вызывается. Кажется, что он работает, когда я запускаю проект, но это не очень помогает тестировать диск приложения.

Кроме того, я понимаю, что могу использовать атрибут [Required] для моего примера, но мой реальный код имеет гораздо более сложную проверку.

Мысли?

4b9b3361

Ответ 1

Это правда, потому что вы не вызывали ничего, что устанавливает его false.

Это обычно происходит во время привязки, но поскольку вы просто передаете модель непосредственно в тесте, вы пропустите это вообще.

Если вы пытаетесь проверить проверку, сделайте это напрямую. Если вы пытаетесь проверить путь ошибки в своем контроллере, ваша организация тестирования может вызвать _controller.ModelState.AddModelError( //...

Ответ 2

Ну, если вы смоделируете поведение привязки модели, вы можете это сделать:

public class YourController : Controller
{

    //some code

    public ViewResult someAction(Model model)
    {
        try
        {
            ValidateModel(model);
        }
        catch
        {
            // deal with errors
        }
    }

    //some code
}

ValidateModel с блоками "try catch" для меня гораздо более читабельны. Но вы все равно можете использовать блоки "if" с помощью метода TryValidateModel

Надеюсь, что это поможет!