2008-11-13 29 views
43

Ben Controller.ViewData.ModelState nasıl test edebilirim? Ben herhangi bir mock framework olmadan yapmayı tercih ederim.ModelState'i nasıl test edebilirim?

+0

daha spesifik olun. Ne için test etmeye çalışıyorsun? Bana ağır bir önemsememek görünen bir düzenleme vergisi, orada ne yazık ki Hataları'nı – skb

cevap

41

Sen elbette verileriniz için Depo Desen kullanıyorsanız bir Mock kullanmak zorunda değilsiniz.

Bazı örnekler: 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

Sanal değiştirici, güzel olurdu. –

+0

IMHO iyi çözüm mvc konveyör kullanmaktır. Bu şekilde, kontrol cihazınızın daha gerçekçi davranışlarını elde edersiniz, model geçerliliğini kadere teslim etmelisiniz - öznitelik doğrulamaları. Aşağıdaki yazıyı açıklıyor (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

Bu yöntemi gerçekten seviyorum. Siz de belirttiğiniz gibi, doğrulama niteliklerine sahip bir modelin düzgün bir şekilde test edilmesi çok daha iyidir. – stevethethread

+0

Bu harika! – Ian1971

+0

Çok kullanışlıdır. Ben genelde bu çerçevenin bir parçası olarak, modeliniz özelliklerini test edilmemesi gerektiğini söylüyor millet ile anlaşmak düşünüyorum, ama bu sizin kontrolör kritik hataları yakalıyor gelecekteki tüm süre onaylamak için kritik olduğunda zamanlar vardır. –

0

yukarıdaki harika cevaplara ekleme, Kontrolör sınıfı içinde korunan TryValidateModel yönteminin bu fantastik kullanımını göz atın.

Basitçe denetleyici devralmasını bir test sınıfı oluşturmak ve TryValidateModel yöntemine modelinizi geçmektedir. İşte bu bağlantı: http://blog.icanmakethiswork.io/2013/03/unit-testing-modelstate.html

Bu çözüm için tam kredi John Reilly ve Marc Talary'e gider. Test Web API için

+2

burada yerine bir blog yayınına kapalı bağlayan daha çözümünü de ekleyiniz – csharpsql

+2

Kişisel link uzantısı yöntemi ' public void BindModelToController (bu Kontrolör kontrolör, T modeli) oluşturabilir ölü. –

10

, denetleyici üzerinde Validate yöntemi kullanın:

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

controller.Validate(model); 
var result = controller.MyMethod(model); 
İlgili konular