IValidatableObject проходит проверку, но StringLength является недействительным

У меня есть тестовый класс с парой тестов, которые проверяют, если сущность 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 собственность сейчас работает. Я обновил весь код для работы.

1 ответ

Решение

Validator.TryValidateObject проверяет только RequiredAttributes (а также другие вещи, такие как атрибуты уровня типа и IValidatableObject реализация) по умолчанию.

Если вам нужно проверить все атрибуты, как StringLength и т.д. вам нужно установить validateAllProperties параметр метода для true

private bool IsValidForPersistance() {
    return Validator.TryValidateObject(this, 
                                       new ValidationContext(this), 
                                       null,
                                       true /* validateAllProperties */);
}
Другие вопросы по тегам