我有一个自定义的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
不包含此自定义属性的键。
它仅包含标准验证属性的属性。
为什么会这样?
测试这些自定义属性的最佳方法是什么?
答案 0 :(得分:43)
您的属性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)
}
答案 1 :(得分:13)
您的自定义验证属性可能取决于其他属性的状态。在这种情况下,您可以使用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);
答案 2 :(得分:0)
我发现IsValid
在诸如字符串之类的简单类型上不能很好地工作。例如。如果您对不是对象的字符串查询参数进行了验证。另外,直接在属性上测试值也很容易,而不必提供整个对象。它还允许检查错误消息。它是这样工作的:
string input = "myteststring";
var myAttribute = new MyAttribute()
var result = attribute.GetValidationResult(input, new ValidationContext(input));
var isSuccess = result == ValidationResult.Success;
var errorMessage = result?.ErrorMessage;
此代码仅测试输入值的验证,而没有其他测试。
P.S。我已经在dotnet核心中对此进行了测试,但我认为这也适用于普通dotnet。