私は通常、これを 2 つに分割します。
- モデルが有効な場合とそうでない場合に、コントローラーが正しく動作するかどうかをテストします。
- ルール エンジンと組み合わせたモデルが正しいエラー メッセージを生成するかどうかをテストします。
論理的根拠は、コントローラーがエラーに対して正しく動作するかどうかに関係なく、モデル自体が正しく検証される場合、アプリケーションは正しく動作するということです。テストのセットアップも簡単になります。
投稿の最も単純なケースでは、すべてが正常な場合はコントローラーを結果ページにリダイレクトし、検証エラーが発生した場合は同じビューを再表示するようにします。
[TestClass]
public class Maintaining_todo_list
{
private TodoController controller;
[TestInitialize]
public void Setup()
{
controller = new TodoController {ControllerContext = new ControllerContext()};
}
[TestMethod]
public void Valid_update_should_redirect_to_list()
{
var result = controller.Edit(1, new TodoItem {Text = "todo"});
result.ShouldRedirectTo("list");
}
[TestMethod]
public void Invalid_update_should_display_same_view()
{
var result = controller.Edit(1, new TodoItem {Text = ""});
result.ShouldDisplayDefaultView();
}
}
モデルは、さまざまなメッセージでさまざまな方法で失敗する可能性があります。
[TestClass]
public class Validating_todo_item
{
[TestMethod]
public void Text_cannot_be_empty()
{
var todo = new TodoItem {Text = ""};
todo.ShouldContainValidationMessage("Text cannot be empty");
}
[TestMethod]
public void Text_cannot_contain_more_than_50_characters()
{
var todo = new TodoItem { Text = new string('a', 51) };
todo.ShouldContainValidationMessage("Text cannot contain more than 50 characters");
}
[TestMethod]
public void Valid_items()
{
new TodoItem { Text = new string('a', 1) }.ShouldBeValid();
new TodoItem { Text = new string('a', 50) }.ShouldBeValid();
}
}
(完全を期すために、ここにテスト ヘルパーを示します)
internal static class AssertionHelpers
{
public static void ShouldRedirectTo(this ActionResult result, string action)
{
var redirect = result as RedirectToRouteResult;
Assert.IsNotNull(redirect);
Assert.AreEqual(action, redirect.RouteValues["action"]);
Assert.IsNull(redirect.RouteValues["controller"]);
}
public static void ShouldDisplayDefaultView(this ActionResult result)
{
var view = result as ViewResult;
Assert.IsNotNull(view);
Assert.AreEqual("", view.ViewName);
}
public static void ShouldContainValidationMessage(this TodoItem todo, string message)
{
var context = new ValidationContext(todo, null, null);
var results = new List<ValidationResult>();
Validator.TryValidateObject(todo, context, results, true);
var errors = results.Select(result => result.ErrorMessage);
foreach (var error in errors)
{
Console.Out.WriteLine(error);
}
Assert.IsTrue(errors.Contains(message));
}
public static void ShouldBeValid(this TodoItem todo)
{
var context = new ValidationContext(todo, null, null);
var results = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(todo, context, results, true);
Assert.IsTrue(isValid);
}
}