Как я могу провести модульное тестирование своего пользовательского атрибута проверки - PullRequest
35 голосов
/ 12 января 2011

У меня есть собственный атрибут проверки класса asp.net mvc. У меня вопрос, как я могу проверить его? Было бы одно дело проверить, что у класса есть атрибут, но это на самом деле не проверило бы, что логика внутри него. Это то, что я хочу проверить.

[Serializable]
[EligabilityStudentDebtsAttribute(ErrorMessage = "You must answer yes or no to all questions")]
public class Eligability
{
    [BooleanRequiredToBeTrue(ErrorMessage = "You must agree to the statements listed")]
    public bool StatementAgree { get; set; }

    [Required(ErrorMessage = "Please choose an option")]
    public bool? Income { get; set; }

..... удалено для краткости }

[AttributeUsage(AttributeTargets.Class)]
public class EligabilityStudentDebtsAttribute : ValidationAttribute
{
    // If AnyDebts is true then 
    // StudentDebts must be true or false

    public override bool IsValid(object value)
    {
        Eligability elig = (Eligability)value;
        bool ok = true;
        if (elig.AnyDebts == true)
        {
            if (elig.StudentDebts == null)
            {
                ok = false;
            }
        }
        return ok;

    }
}

Я попытался написать тест следующим образом, но это не работает:

[TestMethod]
public void Eligability_model_StudentDebts_is_required_if_AnyDebts_is_true()
{

   // Arrange
   var eligability = new Eligability();
   var controller = new ApplicationController();

   // Act
   controller.ModelState.Clear();
   controller.ValidateModel(eligability);
   var actionResult = controller.Section2(eligability,null,string.Empty);

   // Assert
   Assert.IsInstanceOfType(actionResult, typeof(ViewResult));
   Assert.AreEqual(string.Empty, ((ViewResult)actionResult).ViewName);
   Assert.AreEqual(eligability, ((ViewResult)actionResult).ViewData.Model);
   Assert.IsFalse(((ViewResult)actionResult).ViewData.ModelState.IsValid);
}

ModelStateDictionary не содержит ключ для этого пользовательского атрибута. Он содержит только атрибуты для стандартных атрибутов проверки.

Почему это?

Как лучше всего проверить эти пользовательские атрибуты?

Ответы [ 3 ]

44 голосов
/ 12 января 2011

Ваш атрибут EligabilityStudentDebtsAttribute это просто стандартный класс, как и все остальное, просто модульное тестирование метода IsValid(). Если все работает нормально, доверьтесь Framework, этот атрибут работает нормально.

Итак:

[Test]
public void AttibuteTest()
{
   // arrange
   var value = //.. value to test - new Eligability() ;
   var attrib = new EligabilityStudentDebtsAttribute();

   // act
   var result = attrib.IsValid(value);

   // assert
   Assert.That(result, Is.True)
}
13 голосов
/ 13 февраля 2017

Ваш пользовательский атрибут проверки может зависеть от состояния других свойств.В этом случае вы можете использовать статические методы System.ComponentModel.DataAnnotations.Validator, например:

var model = ...
var context = new ValidationContext(model);
var results = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(model, context, results, true);
Assert.True(isValid);
0 голосов
/ 06 мая 2019

Я обнаружил, что IsValid плохо работает с простыми типами, такими как string.Например, если у вас есть проверка на строковый параметр запроса, который не является объектом.Кроме того, проще протестировать значение непосредственно в атрибуте, не предоставляя целый объект.Это также позволяет проверить сообщение об ошибке.Вот как это работает:

string input = "myteststring";
var myAttribute = new MyAttribute()
var result = attribute.GetValidationResult(input, new ValidationContext(input));

var isSuccess = result == ValidationResult.Success;
var errorMessage = result?.ErrorMessage;

Этот код проверяет только проверку вашего входного значения и ничего больше.

PS Я проверил это в ядре dotnet, но я думаю, что это работаети для обычного dotnet.

...