ASP.NET MVC 2 – Unit Tests für / mit Data Annotations

Erst einmal schreibe ich, wo ich alles Tipps/Ideen bekommen habe
http://blog.thomasbandt.de/39/2318/de/blog/aspnet-mvc-2-unit-tests-fuer-data-annotations.html
http://der-albert.com/archive/2010/05/14/input-validierung-im-unit-test-mit-asp-net-mvc-2.aspx

Beim Thomas Brandt, habe ich das meinste her.
Mein Problem war, das ich Validierung von ASP.NET MVC 2 genutzt habe und dann meine Tests nicht mehr geklappt haben. Ich musste feststellen, das die die Validierung im Model nicht funktioniert bei UnitTests

//Model
public class HomeKontakt
{
[RegularExpression(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessageResourceType = typeof(ModelValidation), ErrorMessageResourceName = "MailInvalid")]
[Required(ErrorMessageResourceType = typeof(ModelValidation), ErrorMessageResourceName = "MailRequired")]
public String Mail { get; set; }

[Required(ErrorMessageResourceType = typeof(ModelValidation), ErrorMessageResourceName = "NameRequired")]
public String Name { get; set; }

[Required(ErrorMessageResourceType = typeof(ModelValidation), ErrorMessageResourceName = "SubjectRequired")]
public String Betreff { get; set; }

[Required(ErrorMessageResourceType = typeof(ModelValidation), ErrorMessageResourceName = "TextRequired")]
public String Text { get; set; }
}

Als ich es mitbekommen habe, was mit DataAnnotations alles so tolles geht, war ich sehr schnell begeistert und hatte dann auch sehr schnell das in meinem Projekt umgesetzt.

//Controller
public ActionResult Kontakt(HomeKontakt model)
{
if (ModelState.IsValid)
{
//Mail verschicken
}
return View("Kontakt", model);
}

Die Erweiterungs-Methode “ContainsField” stammt von Thomas Brandt (siehe oben)

//Test
[TestMethod]
public void KontaktSendFehlerMailAdresse()
{
// Arrange
HomeController controller = new HomeController(_Factory, _FS);

// Act
HomeKontakt model = new HomeKontakt()
{
Mail = "test@bla@test.home.de",
// Text = "Ich werde nur getestet",
Betreff = "KontaktSendTest",
Name = "KontaktSendTest"
};

// Assert
var validationResults = new ValidationResults();
Validator.TryValidateObject(model, new ValidationContext(model, null, null), validationResults, true);

Assert.IsTrue(validationResults.ContainsField<HomeKontakt>(m => m.Mail));
Assert.IsTrue(validationResults.ContainsField<HomeKontakt>(m => m.Text));
Assert.AreEqual(validationResults[0].ErrorMessage, Web.Languages.ModelValidation.MailInvalid);
Assert.AreEqual(validationResults[1].ErrorMessage, Web.Languages.ModelValidation.TextRequired);
}

Zeile 21 / 22 (Assert.IsTrue(validationResults.ContainsField(m => m.Mail));) prüft ob in validationResults das Feld “Mail” vorhanden ist, wenn ja, dann ist die Validierung bei dem Feld fehlgeschlagen.
Mit “Assert.AreEqual(validationResults[0].ErrorMessage, Web.Languages.ModelValidation.MailInvalid);” prüfe ich noch zusätzlich ob der Fehldertext, auch der ist, den ich ausgeben möchte. Ich habe die ganzen Texte in einer Resource-Datei ausgelagert.

Leider funktioniert meine “alte Test-Methodik” nicht mehr.

//Alter Test
public void KontaktSendFehlerMailAdresse()
{
// Arrange
HomeController controller = new HomeController(_Factory, _FS);

// Act
HomeKontakt model = new HomeKontakt()
{
Mail = "baum@bla@test.local.de",
// Text = "Ich werde nur getestet",
Betreff = "KontaktSendTest",
Name = "KontaktSendTest"
};
//ERROR
ViewResult result = controller.Kontakt(model) as ViewResult;

// Assert
Assert.IsNotNull(result);

Assert.AreEqual("Kontakt", result.ViewName);

ViewDataDictionary viewData = result.ViewData;
Assert.AreEqual(ModelValidation.MailInvalid, result.ViewData.ModelState["mail"].Errors[0].ErrorMessage, "Fehler in Mail-Adresse");
Assert.IsFalse(viewData.ModelState.IsValid, "Fehler in Mail-Adresse");
}

Bei dem Aufruf von controller.Kontakt(model) bekomme ich dann immer eine FormatException, weil die Mail-Adresse ja nicht dem Format einer E-Mail-Adresse entspricht. In diesen Tests konnte ich wenigstens nich zusätzlich testen, ob ich den richtigen View zurück bekomme. Aber ich werde da jetzt wahrscheinlich nur Tests mit “gültigen Eingaben machen können” und bei “ungültigen Eingaben” muss ich extra Tests machen, die mir nur meine ModelValidation Testen.

Oder habe ich da einen Denkfehler?

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *


8 + 8 =

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>