TDD: Что лучше всего проверять DataAnnotations в ASP.NET MVC 3?

Я участвую в проекте с использованием ASP.NET MVC 3 и DataAnnotations. У нас есть DataAnnotations в классах ViewModels.

Как вы пишете модульные тесты для этих проверок?

Пример ViewModel:

public class AchievementVM
{
    [Required(ErrorMessage = "The title field is required.")]
    [StringLength(100, ErrorMessage = "Title must be 100 characters or less.")]
    public string Title { get; set; }
}

Спасибо!

Ответ 1

.NET framework поставляется с классом Validator, который может использовать вашу логику проверки в изоляции. Код для проверки может выглядеть следующим образом:

var achievement = new AchievementVM();
var context = new ValidationContext(achievement, 
    serviceProvider: null, items: null);
var results = new List<ValidationResult>();

var isValid = Validator.TryValidateObject(achievement, context, results, true);

Assert.IsTrue(results.Any(vr => vr.ErrorMessage == "The title field is required."));

achievement.Title = "Really really long title that violates "
    + "the range constraint and should not be accepted as "
    + "valid input if this has been done correctly.";

Validator.TryValidateObject(achievement, context, results, true);

Assert.IsTrue(results.Any(vr => vr.ErrorMessage == "Title must be 100 characters or less."));

Не нужно настраивать утилиты для поиска атрибутов. Класс Validator выполняет эту работу за вас и заполняет коллекцию ValidationResult так же, как и инфраструктуру MVC.

Хорошую запись по этому методу можно найти на K. Блог Скотта Аллена.

Ответ 2

Поскольку эти аннотации являются очень декларативными, мало смысла писать блок-тесты, которые просто проверяют (с отражением), что методы аннотируются - тесты просто дублируют производственный код. И это все равно оставит возможность, что аннотации не будут использоваться так, как предполагается, что они будут использоваться (возможно, это неправильные аннотации, они находятся в неправильном месте или им не хватает дополнительной конфигурации).

Таким образом, осмысленный тест не будет unit test, а будет интеграционный тест, который гарантирует, что система правильно определит аннотации. Чтобы скорость была разумной, постарайтесь сделать эти интеграционные тесты максимально сфокусированными, создав как можно меньше рамки (что требует глубокого знания структуры - RTFS). Если ничего другого, сквозной тест может проверить правильность использования аннотаций путем анализа HTML и проверки того, что ошибки проверки отображаются, когда в поля вводятся недопустимые данные.

Должно быть необходимо написать всего пару тестов интеграции/сквозного тестирования, чтобы убедиться, что проверка включена. Там не должно быть необходимости проверять каждое поле, когда все они работают одинаково.