2008-11-13 12 views
43

¿Cómo puedo probar Controller.ViewData.ModelState? Preferiría hacerlo sin ningún marco simulado.¿Cómo puedo probar ModelState?

+0

ser más específico. ¿Para qué estás tratando de probarlo? – skb

Respuesta

41

No tiene que usar un simulacro si está utilizando el patrón de repositorio para sus datos, por supuesto.

Algunos ejemplos: http://www.singingeels.com/Articles/Test_Driven_Development_with_ASPNET_MVC.aspx

// Test for required "FirstName". 
    controller.ViewData.ModelState.Clear(); 

    newCustomer = new Customer 
    { 
     FirstName = "", 
     LastName = "Smith", 
     Zip = "34275",  
    }; 

    controller.Create(newCustomer); 

    // Make sure that our validation found the error! 
    Assert.IsTrue(controller.ViewData.ModelState.Count == 1, 
       "FirstName must be required."); 
+1

Un modificador virtual en Errores sería agradable, por desgracia hay un impuesto de arreglos, que me parece un poco pesado. –

+0

En mi humilde opinión, la mejor solución es usar un transportador de mvc. De esta manera, obtiene un comportamiento más realista de su controlador, debe entregar la validación del modelo a su destino: validación de atributos. La publicación siguiente describe esto (http://stackoverflow.com/a/5580363/572612). –

35
//[Required] 
//public string Name { get; set; } 
//[Required] 
//public string Description { get; set; } 

ProductModelEdit model = new ProductModelEdit() ; 
//Init ModelState 
var modelBinder = new ModelBindingContext() 
{ 
    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(
        () => model, model.GetType()), 
    ValueProvider=new NameValueCollectionValueProvider(
         new NameValueCollection(), CultureInfo.InvariantCulture) 
}; 
var binder=new DefaultModelBinder().BindModel(
       new ControllerContext(),modelBinder); 
ProductController.ModelState.Clear(); 
ProductController.ModelState.Merge(modelBinder.ModelState); 

ViewResult result = (ViewResult)ProductController.CreateProduct(null,model); 
Assert.IsTrue(result.ViewData.ModelState["Name"].Errors.Count > 0); 
Assert.True(result.ViewData.ModelState["Description"].Errors.Count > 0); 
Assert.True(!result.ViewData.ModelState.IsValid); 
+0

Me gusta mucho este método. Como dices, es mucho mejor probar un modelo correctamente que haya sido decorado con atributos de validación. – stevethethread

+0

¡Esto es asombroso! – Ian1971

+0

Muy útil. Creo que generalmente estoy de acuerdo con las personas que dicen que no deberían probar las propiedades de su modelo, ya que eso es parte del marco, pero a veces es fundamental confirmar para el futuro que su controlador está detectando errores críticos. –

0

Agregando las grandes respuestas anteriores, echa un vistazo a este fantástico uso del método TryValidateModel protegida dentro de la clase controlador.

Simplemente cree una clase de prueba que hereda del controlador y pase su modelo al método TryValidateModel. Aquí está el enlace: http://blog.icanmakethiswork.io/2013/03/unit-testing-modelstate.html

El crédito total va para John Reilly y Marc Talary por esta solución.

+2

Por favor incluya la solución aquí en lugar de vincular fuera a una entrada de blog – csharpsql

+2

Su enlace es muerto. –

10

Para Web API prueba, utilice el método Validate en el controlador:

var controller = new MyController(); 
controller.Configuration = new HttpConfiguration(); 
var model = new MyModel(); 

controller.Validate(model); 
var result = controller.MyMethod(model); 
Cuestiones relacionadas