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

Тестирование ModelState всегда действует в asp.net mvc

При тестировании моих действий контроллера ModelState всегда действителен.

public class Product
{
    public int Id { get; set; }

    [Required]
    [StringLength(10)]
    public string Name { get; set; }

    [Required]
    public string Description { get; set; }

    [Required]
    public decimal Price { get; set; }
}

И мой контроллер.

public class ProductController : Controller
{
      [HttpPost]
      public ActionResult Create(Product product)
      {
            if (ModelState.IsValid)
            {
                   // Do some creating logic...
                   return RedirectToAction("Display");
            }

             return View(product);              
      }
 }

И тест:

[Test]
public TestInvalidProduct()
{
     var product = new Product();
     var controller = new ProductController();
     controller.Create(product);
     //controller.ModelState.IsValid == true
}

Почему modelState действителен, когда у продукта нет имени, Описание и цена?

4b9b3361

Ответ 1

Проверка выполняется, когда опубликованные данные привязаны к модели представления. Затем модель представления передается в контроллер. Вы пропускаете часть 1 и передаете модель взгляда прямо в контроллер.

Вы можете вручную проверить модель представления с помощью

System.ComponentModel.DataAnnotations.Validator.TryValidateObject()

Ответ 2

Я столкнулся с одной и той же проблемой, и хотя принятый ответ здесь разрешил проблему без проверки, это оставило меня с большим негативным аспектом: он выдавал бы исключение, если бы были ошибки проверки, а не просто установка ModelState.Invalid в false.

Я тестировал это только в Web Api 2, поэтому я не знаю, какие проекты будут доступны, но есть метод ApiController.Validate(object), который принудительно проверяет пройденный объект и устанавливает только ModelState.IsValid в false. Кроме того, вам также необходимо создать экземпляр свойства Configuration.

Добавление этого кода в мой unit test позволило ему работать:

userController.Configuration = new HttpConfiguration();
userController.Validate(addressInfo);

Ответ 3

В другой заметке. Вы должны проверить, что возвращает контроллер, и что возвращенный ActionResult - это то, что вы ожидаете. Тестирование ModelBinder должно выполняться отдельно.

Скажем, вы хотите переключиться на настраиваемое связующее устройство. Вы можете повторно использовать тесты ModelBinder для нового создаваемого ModelBinder. Если ваши бизнес-правила остаются неизменными, вы должны иметь возможность напрямую повторять те же тесты. Однако, если вы смешиваете тесты Controller и ModelBinder, а тест терпит неудачу, вы не знаете, есть ли проблема в контроллере или ModelBinder.

Скажем, вы проверите свою модель, привязав что-то вроде этого:

[Test]
public void Date_Can_Be_Pulled_Via_Provided_Month_Day_Year()
{
    // Arrange
    var formCollection = new NameValueCollection { 
        { "foo.month", "2" },
        { "foo.day", "12" },
        { "foo.year", "1964" }
    };

    var valueProvider = new NameValueCollectionValueProvider(formCollection, null);
    var modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(FwpUser));

    var bindingContext = new ModelBindingContext
    {
        ModelName = "foo",
        ValueProvider = valueProvider,
        ModelMetadata = modelMetadata
    };

    DateAndTimeModelBinder b = new DateAndTimeModelBinder { Month = "month", Day = "day", Year = "year" };
    ControllerContext controllerContext = new ControllerContext();

    // Act
    DateTime result = (DateTime)b.BindModel(controllerContext, bindingContext);

    // Assert
    Assert.AreEqual(DateTime.Parse("1964-02-12 12:00:00 am"), result);
}

Теперь, когда вы ЗНАЛИ, ваша модель связана правильно, вы можете продолжить тестирование Модели с помощью своего контроллера в отдельном тесте, чтобы проверить, вернет ли он правильный результат. Кроме того, вы можете использовать значения привязанной модели для проверки своих атрибутов проверки.

Таким образом, вы можете получить полный набор тестов, которые покажут, если ваше приложение взорвется, на каком уровне он действительно это делает. ModelBinding, Controller или Validation.

Ответ 4

  • Создать экземпляр вашего класса контроллера.
  • Добавить состояние модели и вызов После добавления состояния модели
  • modelState всегда дает false

    controller.ModelState.AddModelError("key", "error message");
    
    var invalidStateResult = _controller.Index();
    
    Assert.IsNotNull(invalidStateResult);
    

Ответ 5

Используйте controller.UpdateModel или controller.TryUpdateModel, чтобы использовать текущий контроллер ValueProvider для привязки некоторых данных и проверки правильности привязки модели до проверки того, что ModelState.IsValid

Ответ 6

Если вы хотите проверить действие действия проверки, вы можете просто добавить ModelStateError:

ModelState.AddModelError("Password", "The Password field is required");

Ответ 7

Попробуйте контроллер. ViewModel.ModelState.IsValid вместо контроллера .ModelState.IsValid.