Perché Assert.AreEqual (T obj1, Tobj2) fallisce con array di byte identici


86

Ho due array di byte identici nel seguente segmento di codice:

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

Entrambi gli array sono identici fino al byte. In questo scenario, perché Assert.AreEqual fallisce?


1
Come nota, se si utilizza NUnit, i confronti dei valori degli array sono supportati dalla versione 2.2, quindi Assert.AreEqualfunzionerà correttamente .
AJ Richardson

Risposte:


141

Assert.Equalstest utilizzando il Equalsmetodo, che per impostazione predefinita utilizza l'uguaglianza dei riferimenti e, poiché sono oggetti diversi, non sono uguali. Ti consigliamo di confrontare ogni byte nell'array e verificare che siano uguali. Un modo per farlo è convertirli in qualcosa che implementi ICollection e utilizzare invece CollectionAssert.AreEqual () .


3
Un array è già un ICollection, ovviamente. È anche un file IList. È importante che la tua "uguaglianza di raccolta" consideri l'ordinamento (cioè le raccolte devono essere uguali come sequenze, non solo come set matematici).
Jeppe Stig Nielsen

Questa risposta è sbagliata! "Assert.AreEqual controlla che objectOne.Equals (objectTwo) restituisca true." (vedi blog.robustsoftware.co.uk/2009/05/… ). Se vuoi controllare l'uguaglianza dei riferimenti devi usare Assert.AreSame (). L'output di Assert.AreEqual () dipende completamente dal tipo di oggetto.
user1027167

@ user1027167 - chiarito. In questo caso non stava cercando di verificare l'uguaglianza dei riferimenti, ma se contenevano lo stesso contenuto, quindi non pensavo che la risposta richiedesse quel tipo di precisione.
tvanfosson

2
Consiglio di guardare anche gli altri metodi CollectionAssert ... Da quanto tempo utilizzo questo framework di unit test e non conosco CollectionAssert! L'ho fatto manualmente per troppo tempo e mi sento piuttosto stupido.

44

Perché gli array non sovrascrivono Equals.

Non hai detto quale framework di test stai usando, ma fondamentalmente dipenderà da quel framework per array di casi speciali. Puoi sempre implementare il tuo metodo di supporto per farlo, ovviamente. A volte l'ho fatto. Per un hack veloce e sporco, se stai usando .NET 3.5 puoi usare il Enumerable.SequenceEqualmetodo di estensione:

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

Un metodo di supporto personalizzato potrebbe darti maggiori dettagli su come differiscono, ovviamente. Potresti trovare i metodi MoreLINQ.TestExtensionsutili, sebbene siano anche abbastanza approssimativi e pronti.


Sto usando unit test VSTS. C'è un'asserzione alternativa incorporata che posso usare, o fare un ciclo for e confrontare i byte, se sono tutti uguali, quindi affermare?
David Anderson,

Temo di non aver utilizzato gli unit test VSTS, ma la raccomandazione di tvanfosson sembra appropriata.
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
Perché convertire il byte [] in una stringa per effettuare il confronto. Non è necessario e, immagina, l'errore potrebbe essere nella conversione stessa, non nel byte []
Luis Filipe

2

Il metodo Assert.AreEqual sotto il cofano finirà per essere predefinito su Object.Equals () per valori non nulli. L'implementazione predefinita di Object.Equals () è l'uguaglianza referenziale. I 2 array sono identici dal punto di vista del valore ma della differenza rispetto al riferimento e quindi non saranno considerati uguali.


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

confronterò le cose ... per me funziona ..


0

Creato un semplice metodo di supporto:

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]);
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.