TDD - тестирование бизнес-правил / валидация в ASP.NET MVC - PullRequest
3 голосов
/ 29 марта 2010

Я использую четкую архитектуру, поэтому я могу легко использовать макеты и т. Д. В своих модульных тестах и ​​/ или во время TDD. У меня довольно сложные бизнес-правила, и я хотел бы проверить их на уровне контроллера. Мне просто интересно, как другие люди делают это?

Для меня проверка правильности бизнес-правил на трех уровнях:

(1) Уровень свойства (например, требуется свойство) (2) Внутренний уровень свойства (например, дата начала <дата окончания) (3) Уровень персистентности (например, имя уникально, родитель не может быть дочерним по отношению к ребенку) </p>

Моя структура проверки также назначает ошибки свойствам. Мне просто интересно, что делают другие люди? Вы пишете тест для каждого бизнес-правила и проверяете, назначено ли правильное сообщение об ошибке правильному свойству (то есть, глядя на ASP.MVC ModelState)?

Надеюсь, мой вопрос имеет смысл. Большое спасибо!

С наилучшими пожеланиями,

Christian

1 Ответ

0 голосов
/ 30 декабря 2010

Я обычно делю это на две части:

  1. Проверьте, правильно ли работает контроллер, когда модель действительна, а когда нет.
  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);
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...