我有一个带有几个测试的测试类,用于检查实体是否IsValid
。我开始使用IValidatableObject
进行自己的自定义验证,但我坚持使用正确的验证技术。
这是我的测试类:
[TestFixture]
public class StudentTests {
private static Student GetContactWithContactInfo()
{
return new Student(new TestableContactRepository())
{
Phone = "7275551111"
};
}
private static Student GetContactWithoutContactInfo()
{
return new Student(new TestableContactRepository());
}
[Test]
public void Student_Saving_StudentHasInfo_IsValid ()
{
// Arrange
Student student = GetContactWithContactInfo();
// Act
student.Save();
// Assert
Assert.IsTrue(student.IsValid);
}
[Test]
public void Student_Saving_StudentDoesNotHaveInfo_IsNotValid ()
{
// Arrange
Student student = GetContactWithoutContactInfo();
// Act
student.Save();
// Assert
Assert.IsFalse(student.IsValid);
}
}
这是我的实体:
public class Student : IValidatableObject
{
private readonly IContactRepository contactRepository;
public Student(IContactRepository _contactRepository)
{
contactRepository = _contactRepository;
Contacts = new List<Student>();
}
[Required]
public int Id { get; private set; }
[StringLength(10, MinimumLength = 10)]
public string Phone { get; set; }
public List<Student> Contacts { get; private set; }
public bool IsValid { get; private set; }
public void Save()
{
if (IsValidForPersistance())
{
IsValid = true;
Id = contactRepository.Save();
}
}
private bool IsValidForPersistance()
{
return Validator.TryValidateObject(this, new ValidationContext(this), null, true);
}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (string.IsNullOrEmpty(Phone) && Contacts.All(c => string.IsNullOrEmpty(c.Phone)))
yield return new ValidationResult("The student or at least one contact must have a phone number entered", new[] { "Phone Number" });
}
}
您可以通过调用IsValid
来查看IsValidForPersistance
的测试测试。 Validate
最终会有更多验证。
上述测试均使用此方法通过,但下面的测试也通过但不应该通过。
[Test]
public void Student_Saving_HasContactInfoWithInvalidLength_IsNotValid()
{
// Arrange
Contact student = GetContactWithoutContactInfo();
student.Phone = "string";
// Act
student.Save();
// Assert
Assert.IsFalse(student.IsValid);
}
这里我设置了自己的Phone
无效长度字符串的值。我希望验证失败,因为StringLength
注释设置为最小和最多10个字符。
为什么会过去?
更新
自定义验证存在问题,使用更改更新了代码。除了nemesv关于private
属性上没有Phone
修饰符的建议,它现在有效。我已将所有代码更新为正常工作。
答案 0 :(得分:16)
Validator.TryValidateObject 仅检查 RequiredAttribute
(以及类型级属性和IValidatableObject
实现等其他内容)。
如果您需要验证所有属性,例如StringLength
等,则需要将方法的validateAllProperties
参数设置为true
private bool IsValidForPersistance() {
return Validator.TryValidateObject(this,
new ValidationContext(this),
null,
true /* validateAllProperties */);
}