2009-09-03 6 views
77

Mam dwie identyczne tablice bajtów w następującym segmentu kodu:Dlaczego Assert.AreEqual (T obj1, Tobj2) nie identycznymi tablicami bajtów

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

Obie tablice są identyczne w dół do samego bajta. W tym scenariuszu dlaczego Assert.AreEqual się nie powiodło?

+1

Na marginesie, jeśli używasz NUnit porównania wartości tablice są obsługiwane od wersji 2.2, więc 'Assert.AreEqual' będzie działać poprawnie. –

Odpowiedz

123

Assert.Equals przy użyciu metody Equals, która domyślnie używa równości odniesienia, a ponieważ są to różne obiekty, nie są one równe. Będziesz chciał porównać każdy bajt w tablicy i sprawdzić, czy są równe. Jednym ze sposobów na to jest przekonwertowanie ich na coś, co implementuje ICollection i zamiast tego użyj CollectionAssert.AreEqual().

+2

tak, to załatwiło sprawę. dzięki! –

+3

Tablica jest już "ICollection", oczywiście. To nawet "ILIST". Ważne jest, aby "równość kolekcji" uwzględniała porządek (to znaczy zbiory muszą być równe ciągom, a nie tylko zestawy matematyczne). –

+0

To odpowiedź jest błędna! "Assert.AreEqual sprawdza, czy objectOne.Equals (objectTwo) zwróci true." (zobacz http://blog.robustsoftware.co.uk/2009/05/difference-between-areequal-and-aresame.html). Jeśli chcesz sprawdzić równość odniesienia, musisz użyć Assert.AreSame(). Wyjście Assert.AreEqual() zależy w pełni od typu obiektu. – user1027167

35

Ponieważ tablice nie zastępują Equals.

Nie powiedziałeś, z której struktury testowej korzystasz, ale w zasadzie to właśnie do tego układu będą należały macierze specjalne. Zawsze możesz oczywiście zastosować własną metodę pomocniczą. Czasami to robiłem. Dla szybkiego i brudne siekać, jeśli używasz .NET 3.5 można użyć metody Enumerable.SequenceEqual rozszerzenia:

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

Niestandardowa metoda pomocnika może dać więcej szczegółów na temat w jaki sposób różnią się one, oczywiście. Możesz znaleźć metody w MoreLINQ.TestExtensions pomocne, chociaż są one dość szorstkie i gotowe.

+0

Używam testów jednostkowych VSTS. Czy istnieje wbudowane zastępcze potwierdzenie, którego mogę użyć, lub zrobić pętlę for i porównać bajty, jeśli wszystkie są takie same, a następnie twierdzą? –

+0

Obawiam się, że nie użyłem testów jednostkowych VSTS - ale zalecenie tvanfosson wygląda na właściwe. –

+0

Jego odpowiedź zadziałała świetnie, dzięki Jon! –

2

Metoda Assert.AreEqual pod maską kończy się domyślnie Object.Equals() dla wartości innych niż NULL. Domyślną implementacją Object.Equals() jest równość referencyjna. Te 2 tablice są identyczne pod względem wartości, ale mają różną wartość odniesienia i dlatego nie będą uznawane za równe.

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

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

Po co konwertować bajt [] na ciąg znaków, aby dokonać porównania. Nie jest to konieczne i wyobraź sobie, że błąd może dotyczyć samej konwersji, a nie bajtu [] –

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

porówna rzeczy ... To działa dla mnie ..

0

Utworzono prosta metoda pomocnika:

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]); 
    } 
} 
Powiązane problemy