2016-06-01 12 views
7

Próbowałem zrobić to działa i zrobił wiele wyszukiwania google/stackoverflow bez szczęścia w ogóle.ModelState.IsValid zawsze prawdziwe podczas testowania kontrolera w Asp.Net MVC Web Api

Mam prosty model:

public class MovieModel 
{ 
    public string Id { get; set; } 

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

metody w kontrolerze:

// POST: api/Movies 
public IHttpActionResult Post([FromBody]MovieModel movieModel) 
{ 
    if (ModelState.IsValid) 
    { 
     //Code 
    } 
} 

oraz metody badania (to jest test integracji, ale to samo stałoby się w testach jednostkowych):

[TestMethod] 
public void MoviesController_Post_Without_Name() 
{ 
    // Arrange 
    var model = new MovieModel(); 
    model.Name = ""; 

    // Act 
    var result = controller.Post(model); 

    // Assert 
    Assert.IsInstanceOfType(result, typeof(InvalidModelStateResult)); 
    Assert.AreEqual(6, controller.Get().Count()); 
} 

Pomimo faktu, że model jest wyraźnie nieprawidłowy, zawsze należy ocenić właściwość IsValid na wartość true.

Próbowałem wielu podejść do tej pory bez powodzenia.

Odpowiedz

5

Twoje rozwiązanie prawdopodobnie działa, ale lepszym sposobem jest użycie metody ApiController.Validate.

public void MoviesController_Post_Without_Name() 
{ 
    // Arrange 
    var model = new MovieModel(); 
    model.Name = ""; 

    // Act 
    controller.Validate(model); //<---- use the built-in method 
    var result = controller.Post(model); 

    // Assert 
    Assert.IsInstanceOfType(result, typeof(InvalidModelStateResult)); 
    Assert.AreEqual(6, controller.Get().Count()); 
} 
+0

Próbowałem tego. Metoda Validate wcześniej, ale nie istnieje. Używam MVC 5. –

+0

W referencji microsoft przedstawiono metodę sprawdzania poprawności, dla wersji 5 MVC, ale po prostu nie działa, ani IntelliSense, ani kompilacja nie działają. –

+0

@ AndréBaptista Dlaczego mówisz o MVC? 'ApiController' jest klasą Web API i znajduje się w' System.Web.Http'. Upewnij się, że dodałeś poprawne pakiety NuGet do projektu testowego. –

4

Dzięki this strona, znalazłem się rozwiązanie:

private void SimulateValidation(object model) 
{ 
    // mimic the behaviour of the model binder which is responsible for Validating the Model 
    var validationContext = new ValidationContext(model, null, null); 
    var validationResults = new List<ValidationResult>(); 
    Validator.TryValidateObject(model, validationContext, validationResults, true); 
    foreach (var validationResult in validationResults) 
    { 
     this.controller.ModelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage); 
    } 
} 

włącznie jednej linii w metodzie badania jak ten:

public void MoviesController_Post_Without_Name() 
{ 
    // Arrange 
    var model = new MovieModel(); 
    model.Name = ""; 

    // Act 
    SimulateValidation(model); 
    var result = controller.Post(model); 

    // Assert 
    Assert.IsInstanceOfType(result, typeof(InvalidModelStateResult)); 
    Assert.AreEqual(6, controller.Get().Count()); 
} 

Hope, który pomaga komuś, byłoby to zapisane mnie kilka godzin polowania na sieć.

+0

działa to dla mnie, ale nie z modeli zagnieżdżonych – MattjeS

+1

pracował Rdzenia 2.0 dla zagnieżdżonych prostu zrobić 'SimulateValidation (modelu); SimulateValidation (model.child); ' – ono2012

+0

Dziękuję bardzo @Andre Baptista, to działa dla mnie –

Powiązane problemy