Por que Assert.AreEqual (T obj1, Tobj2) falha com matrizes de bytes idênticas


86

Tenho duas matrizes de bytes idênticas no seguinte segmento de código:

    /// <summary>
    ///A test for Bytes
    ///</summary>
    [TestMethod()]
    public void BytesTest() {
        byte[] bytes = Encoding.UTF8.GetBytes(Properties.Resources.ExpectedPacketData);
        TransferEventArgs target = new TransferEventArgs(bytes);

        byte[] expected = Encoding.UTF8.GetBytes(Properties.Resources.ExpectedPacketValue);
        byte[] actual;
        actual = target.Bytes;

        Assert.AreEqual(expected, actual);
    }

Ambas as matrizes são idênticas até o byte. Nesse cenário, por que Assert.AreEqual falharia?


1
Como uma observação, se você usar o NUnit, comparações de valor de matrizes são suportadas desde a versão 2.2, portanto Assert.AreEqual, funcionarão bem.
— AJ Richardson

Respostas:


139

Assert.Equalstesta usando o Equalsmétodo, que por padrão usa igualdade de referência e, por serem objetos diferentes, não são iguais. Você vai querer comparar cada byte na matriz e verificar se eles são iguais. Uma maneira de fazer isso é convertê-los em algo que implemente ICollection e usar CollectionAssert.AreEqual () .


3
Um array já é um ICollection, é claro. É até um IList. É importante que sua "igualdade de coleção" considere a ordenação (isto é, as coleções devem ser iguais como sequências, não apenas como conjuntos matemáticos).
— Jeppe Stig Nielsen

Esta resposta está errada! "Assert.AreEqual verifica se objectOne.Equals (objectTwo) retornará verdadeiro." (consulte blog.robustsoftware.co.uk/2009/05/… ). Se você quiser verificar a igualdade de referência, você deve usar Assert.AreSame (). A saída de Assert.AreEqual () depende totalmente do tipo de objeto.
— user1027167

@ user1027167 - esclarecido. Nesse caso, ele não estava tentando verificar a igualdade de referência, mas se elas continham o mesmo conteúdo, então não achei que a resposta precisasse desse tipo de precisão.
— tvanfosson

2
Eu recomendo olhar para os outros métodos CollectionAssert também ... Há quanto tempo eu uso esta estrutura de teste de unidade e não conheço CollectionAssert! Tenho feito isso manualmente há muito tempo e me sinto muito idiota.

44

Porque os arrays não substituem Equals.

Você não disse qual framework de teste está usando, mas basicamente caberia a esse framework os arrays de casos especiais. Você sempre pode implementar seu próprio método auxiliar para fazer isso, é claro. Eu tenho feito isso algumas vezes. Para um hack rápido e sujo, se você estiver usando .NET 3.5, poderá usar o Enumerable.SequenceEqualmétodo de extensão:

Assert.IsTrue(actual.SequenceEqual(expected));

Um método auxiliar personalizado pode fornecer mais detalhes sobre como eles diferem, é claro. Você pode achar os métodos MoreLINQ.TestExtensionsúteis, embora eles também sejam bastante rudimentares e prontos.


Estou usando testes de unidade VSTS. Existe uma asserção alternativa interna que eu possa usar ou fazer um loop for e comparar os bytes, se todos forem iguais, então afirmar?
— David Anderson,

Infelizmente, não usei testes de unidade VSTS - mas a recomendação de tvanfosson parece apropriada.
— Jon Skeet,

5
//Initialize your arrays here
byte[] array1 = new byte[0];
byte[] array2 = new byte[0];

Assert.AreEqual(System.Convert.ToBase64String(array1),
                System.Convert.ToBase64String(array2));

4
Por que converter o byte [] em uma string para fazer a comparação. É desnecessário e, imagina, o erro pode estar na conversão em si, não no byte []
— Luis Filipe

2

O método Assert.AreEqual subjacente acabará assumindo o padrão Object.Equals () para valores não nulos. A implementação padrão de Object.Equals () é a igualdade referencial. As 2 matrizes são idênticas em termos de valor, mas diferem em termos de referência e, portanto, não serão consideradas iguais.


0
byte[] a = new byte[] {x, y, z...};
byte[] b = new byte[] {x, y, z...};
assertArrayEquals(a , b );

vai comparar as coisas ... Funciona para mim ..


0

Método auxiliar simples criado:

private static void CompareArrays<T>(T[] expected, T[] actual)
{
    Assert.AreEqual(expected == null, actual == null, "Expected {0}null value and {1}null found.", expected == null ? "" : "not", actual == null ? "" : "not");
    if (expected == null || actual == null)
            return;

    Assert.AreEqual(expected.LongLength, actual.LongLength, "Expected Length is {0} actual: {1}", expected.LongLength, actual.LongLength);

    for (int i = 0; i < expected.Length; i++)
    {
        Assert.AreEqual(expected[i], actual[i], "Values on index {0} are not equal. Expected {1} actual: {2}", i, expected[i], actual[i]);
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.