Mengapa Assert.AreEqual (T obj1, Tobj2) gagal dengan array byte identik

86

Saya memiliki dua array byte identik di segmen kode berikut:

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

Kedua larik identik hingga satu byte. Dalam skenario ini, mengapa Assert.AreEqual gagal?

David Anderson
sumber
1
Sebagai catatan, jika Anda menggunakan NUnit, perbandingan nilai array didukung sejak versi 2.2, jadi Assert.AreEqualakan berfungsi dengan baik.
AJ Richardson

Jawaban:

141

Assert.Equalstes menggunakan Equalsmetode, yang secara default menggunakan persamaan referensi dan, karena mereka adalah objek yang berbeda, mereka tidak sama. Anda akan ingin membandingkan setiap byte dalam larik dan memverifikasi bahwa keduanya sama. Salah satu cara untuk melakukannya adalah mengonversinya menjadi sesuatu yang mengimplementasikan ICollection dan sebagai gantinya gunakan CollectionAssert.AreEqual () .

tvanfosson.dll
sumber
3
Sebuah array ICollectiontentu saja sudah menjadi sebuah . Ini bahkan IList. Penting bahwa "persamaan koleksi" Anda mempertimbangkan pengurutan (yaitu, koleksi harus sama dengan urutan, tidak hanya sebagai kumpulan matematika).
Jeppe Stig Nielsen
Jawaban ini salah! "Assert.AreEqual memeriksa bahwa objectOne.Equals (objectTwo) akan mengembalikan nilai true." (lihat blog.robustsoftware.co.uk/2009/05/… ). Jika Anda ingin memeriksa kesetaraan referensi, Anda harus menggunakan Assert.AreSame (). Output dari Assert.AreEqual () bergantung sepenuhnya pada tipe objek.
pengguna1027167
@ user1027167 - diklarifikasi. Dalam hal ini dia tidak mencoba untuk memeriksa kesetaraan referensi tetapi apakah mereka berisi konten yang sama, jadi saya tidak berpikir jawabannya membutuhkan ketepatan semacam itu.
tvanfosson
2
Saya sarankan melihat metode CollectionAssert lainnya juga ... Berapa lama saya telah menggunakan kerangka pengujian unit ini dan tidak mengetahui tentang CollectionAssert! Saya telah melakukannya secara manual terlalu lama dan merasa sangat bodoh.
44

Karena array tidak menimpa Equals.

Anda belum mengatakan kerangka pengujian mana yang Anda gunakan, tetapi pada dasarnya itu akan tergantung pada kerangka kerja itu untuk array kasus khusus. Anda selalu bisa mengimplementasikan metode helper Anda sendiri untuk melakukan itu, tentu saja. Saya terkadang melakukannya. Untuk peretasan cepat dan kotor, jika Anda menggunakan .NET 3.5 Anda dapat menggunakan Enumerable.SequenceEqualmetode ekstensi:

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

Metode pembantu khusus tentu saja dapat memberi Anda lebih banyak detail tentang perbedaannya. Anda mungkin menemukan metode ini MoreLINQ.TestExtensionsbermanfaat, meskipun cukup kasar dan siap juga.

Jon Skeet
sumber
Saya menggunakan tes unit VSTS. Apakah ada pernyataan alternatif bawaan yang dapat saya gunakan, atau lakukan perulangan dan bandingkan byte, jika semuanya sama, lalu tegaskan?
David Anderson
Saya khawatir saya belum pernah menggunakan tes unit VSTS - tetapi rekomendasi tvanfosson terlihat sesuai.
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));
José Brazeta
sumber
4
Mengapa mengubah byte [] menjadi string untuk membuat perbandingan. Itu tidak perlu dan, bayangkan, kesalahan bisa jadi dalam konversi itu sendiri, bukan pada byte []
Luis Filipe
2

Metode Assert.AreEqual di bawah tenda akan menjadi default ke Object.Equals () untuk nilai non-null. Implementasi default Object.Equals () adalah persamaan referensial. 2 array adalah nilai yang identik bijaksana tetapi referensi perbedaan bijaksana dan karenanya tidak akan dianggap sama.

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

akan membandingkan hal-hal ... Berhasil untuk saya ..

pengguna2682078
sumber
0

Membuat metode pembantu sederhana:

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]);
    }
}
Gh61
sumber