2012-09-01 28 views
7

Tôi có một lớp thử nghiệm với một vài kiểm tra để kiểm tra xem thực thể IsValid. Tôi đã chuyển sang sử dụng IValidatableObject từ việc xác thực tùy chỉnh của riêng mình nhưng tôi bị kẹt với kỹ thuật xác thực chính xác.IValidatableObject vượt qua xác thực nhưng StringLength là không hợp lệ

Đây là class Test của tôi:

[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); 
    } 
} 

Đây là thực thể của tôi:

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" }); 
    } 
} 

Như bạn có thể thấy các thử nghiệm kiểm tra cho IsValid bằng cách gọi IsValidForPersistance. Validate cuối cùng sẽ có xác nhận hợp lệ hơn.

Các bài kiểm tra trên đều vượt qua bằng cách sử dụng phương pháp này nhưng bài kiểm tra dưới đây cũng vượt qua nhưng không nên.

[Test] 
public void Student_Saving_HasContactInfoWithInvalidLength_IsNotValid() 
{ 
    // Arrange 
    Contact student = GetContactWithoutContactInfo(); 
    student.Phone = "string"; 

    // Act 
    student.Save(); 

    // Assert 
    Assert.IsFalse(student.IsValid); 
} 

Ở đây tôi đặt giá trị Phone của riêng mình có chuỗi dài không hợp lệ. Tôi hy vọng xác thực không thành công do chú thích StringLength được đặt ở tối thiểu và tối đa 10 ký tự.

Tại sao điều này lại xảy ra?

Cập nhật Đã xảy ra sự cố với xác thực tùy chỉnh, đã cập nhật mã với thay đổi. Cùng với đề xuất từ ​​nemesv về việc không có công cụ sửa đổi private trên thuộc tính Phone, tính năng này hiện hoạt động. Tôi đã cập nhật tất cả mã để hoạt động.

+0

Tôi đang tìm vào liên kết này ngay bây giờ vì nó có một bản demo dự án. Dự án triển khai một số lớp trợ giúp bổ sung hoạt động với Trình xác thực. http://www.codeproject.com/Articles/256183/DataAnnotations-Validation-for-Beginner –

Trả lời

13

Validator.TryValidateObjectchỉ kiểm tra các RequiredAttribute s (và cũng những thứ khác như các thuộc tính mức loại và IValidatableObject thực hiện) theo mặc định.

Nếu bạn cần phải xác nhận tất cả các thuộc tính như StringLength vv bạn cần phải đặt validateAllProperties tham số của phương pháp này để true

private bool IsValidForPersistance() { 
    return Validator.TryValidateObject(this, 
             new ValidationContext(this), 
             null, 
             true /* validateAllProperties */); 
} 
+0

Tôi đã cập nhật mã của mình và có giá trị 'validateAllProperties' được đặt thành true ngay bây giờ nhưng tôi vẫn nhận được kết quả tương tự. Bài kiểm tra tương tự vẫn chạy như thể nó hợp lệ –

+0

Bạn mã hoạt động với tôi với 'validateAllProperties = true'. Chỉ có một điều tôi đã thay đổi trong thuộc tính Điện thoại của bạn 'public string Phone {private get; bộ; } 'Tôi đã làm cho công chúng nhận được vì vậy nó nên được' công cộng chuỗi điện thoại {có được; bộ; } ' – nemesv