Pergunta

Eu estou escrevendo (tentando escrever) testes de unidade para um aplicativo do WPF.

Os objetos de negócios que a INTERFACE do usuário liga para implementar IDataErrorInfo, de tal forma que quando eu ValidatesOnDataErrors=True, a meu Ver, xaml, o erro indexador (isso [a]) é chamado sempre que o setter para o dependente objeto de negócios é chamado.Essa parte é grande.

Agora, se eu chamar que mesmo setter de propriedade de um unitTest, ele nunca chama o erro indexador.Como faço para forçar o IDataErrorInfo indexador para ser avaliado a partir de dentro de um teste de unidade?

apenas para ilustração, aqui é um dos meus simples erro de indexadores que contém um Nome de propriedade.Definição de 'meuobjeto.Nome = string.Vazio;' chamar o setter, mas não o erro indexador quando eu faço isso na minha testes de unidade.

        public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            IsDirty = true;
            OnPropertyChanged("Name");
        }
    }

        #region IDataErrorInfo

    public Dictionary<string, string> ErrorCollection;

    public string this[string property]
    {
        get
        {
            string msg = null;
            switch (property)
            {
                case "Name":
                    if (string.IsNullOrEmpty(Name))
                        msg = "ICU Name is required.";
                    else if (Name.Length < 4)
                        msg = "ICU Name must contain at least 4 characters.";
                    else if (_parent.Units.AsEnumerable().Count(u => u.Name == Name) > 1)
                        msg = Name + " already exists, please change to a different Name.";
                    break;
            }


            if (msg != null && !ErrorCollection.ContainsKey(property))
                ErrorCollection.Add(property, msg);
            if (msg == null && ErrorCollection.ContainsKey(property))
                ErrorCollection.Remove(property);

            return msg;
        }
    }

    public string Error
    {
        get { return null; }
    }
    #endregion

Obrigado!

Foi útil?

Solução

O que eu gostaria de fazer um teste de unidade é definir o valor de Nome e, em seguida, chamar explicitamente o indexador para verificar o erro.

Você pode ligar o evento PropertyChanged no teste de unidade, mas eu não acho que faz sentido, como seria, então, temos que, de alguma forma, notificar o método de teste que o evento foi recebido e, em seguida, você tem que chamar o indexador de qualquer maneira.

Outras dicas

Você precisa se conectar no PropertyChanged Evento você mesmo e, quando seu manipulador for chamado, ligue para o indexador com o nome da propriedade. Ou não se conecte ao evento e ligue para o indexador com o nome da propriedade que você está testando.

É isso que .Net faz. Ele chama o indexador com nomes de propriedades.

MyClass mc = new MyClass();
mc.Name = "abc";
string error = mc["Name"];

Os seguintes testes de Nunit chamaram o indexador para a propriedade Nome e validar a mensagem de erro.

[TestFixture]
public class MyClassTests
{
    [TestCase("", "ICU Name is required.")]
    [TestCase("A Valid Name", null)]
    public void ValidationIcuNameIsRequired(string name, string expectedResult)
    {
        // Arrange 
        var systemUnderTest = new MyClass();

        // Act
        systemUnderTest.Name = name;

        // Assert
        Assert.AreEqual(expectedResult, systemUnderTest[nameof(systemUnderTest.Name)]);
    }

    [TestCase("a", "ICU Name must contain at least 4 characters.")]
    [TestCase("ab", "ICU Name must contain at least 4 characters.")]
    [TestCase("abc", "ICU Name must contain at least 4 characters.")]
    [TestCase("abcd", null)]
    [TestCase("abcde", null)]
    public void ValidationIcuNameLongerThanThreeCharacters(string name, string expectedResult)
    {
        // Arrange 
        var systemUnderTest = new MyClass();

        // Act
        systemUnderTest.Name = name;

        // Assert
        Assert.AreEqual(expectedResult, systemUnderTest[nameof(systemUnderTest.Name)]);
    }

    [Test]
    public void ValidationParentDoesNotExist()
    {
        // Arrange
        var systemUnderTest = new MyClass();
        string icuName = "TestName";            
        systemUnderTest.Parent.Units.Add(new Unit() {Name = icuName });

        // Act
        systemUnderTest.Name = icuName;

        // Assert
        Assert.AreEqual(icuName + " already exists, please change to a different Name.", systemUnderTest[nameof(systemUnderTest.Name)]);
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top