true side net mvc isvalid errors asp addmodelerror c# asp.net-mvc asp.net-mvc-3 unit-testing modelstate

side - required c# mvc



Probar ModelState siempre es vĂ¡lido en asp.net mvc (7)

  1. Crear instancia de su clase de controlador.
  2. Agregar estado de modelo y llamar Después de agregar estado de modelo
  3. El estado del modelo siempre da falso.

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

Al probar las acciones de mi controlador, ModelState siempre es válido.

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; } }

Y mi controlador.

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

Y prueba:

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

¿Por qué el modelState es válido cuando el producto no tiene un nombre, descripción y precio?


En otra nota. En realidad, debería probar qué devuelve el controlador y que el resultado de la acción devuelto es lo que espera. La prueba del ModelBinder se debe hacer por separado.

Supongamos que desea cambiar a un archivador de modelo personalizado. Podría reutilizar las pruebas de ModelBinder para el nuevo ModelBinder que está creando. Si las reglas de su negocio siguen siendo las mismas, debería poder reutilizar directamente las mismas pruebas. Sin embargo, si combina la prueba del controlador y las pruebas de ModelBinder y la prueba falla, no sabe si el problema está en el controlador o en el ModelBinder.

Digamos que prueba su modelo uniendo algo como esto:

[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); }

Ahora que SABES que tu modelo está correctamente enlazado, puedes continuar probando el Modelo con tu controlador en una prueba separada para verificar si te devuelve el resultado correcto. Además, puede usar los valores de modelo enlazados para probar sus atributos de validación.

De esta manera, puede obtener un conjunto completo de pruebas que revelarán, si su aplicación explota, en qué nivel realmente lo hace. ModelBinding, Controller o Validación.


La validación ocurre cuando los datos publicados están vinculados al modelo de vista. El modelo de vista se pasa al controlador. Está saltando la parte 1 y pasando un modelo de vista directamente a un controlador.

Puede validar manualmente un modelo de vista usando

System.ComponentModel.DataAnnotations.Validator.TryValidateObject()


Probar el controlador. ViewModel .ModelState.IsValid en lugar de controller.ModelState.IsValid.


Si desea probar el comportamiento de su acción de validación, simplemente puede agregar ModelStateError:

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


Use controller.UpdateModel o controller.TryUpdateModel para usar el ValueProvider actual del controlador para vincular algunos datos y activar la validación de enlace del modelo antes de verificar si ModelState.IsValid


Me he encontrado con el mismo problema y aunque la respuesta aceptada aquí resolvió el problema de "no validación", me dejó con un gran aspecto negativo: generaría una excepción cuando hubiera errores de validación en lugar de simplemente establecer ModelState.Invalid a false .

Solo probé esto en Web Api 2, así que no sé qué proyectos tendrán esto disponible, pero hay un método ApiController.Validate(object) que fuerza la validación en el objeto pasado y solo establece el ModelState.IsValid en false . Además también tendrás que crear una instancia de la propiedad de Configuration .

Agregar este código a mi prueba de unidad permitió que funcionara:

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