เหตุใด Assert.AreEqual (T obj1, Tobj2) จึงล้มเหลวด้วยอาร์เรย์ไบต์ที่เหมือนกัน


86

ฉันมีอาร์เรย์ไบต์ที่เหมือนกันสองอาร์เรย์ในโค้ดส่วนต่อไปนี้:

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

อาร์เรย์ทั้งสองมีค่าเท่ากับไบต์มาก ในสถานการณ์นี้เหตุใด Assert.AreEqual จึงล้มเหลว


1
โปรดทราบว่าหากคุณใช้ NUnit การเปรียบเทียบค่าของอาร์เรย์จะได้รับการสนับสนุนตั้งแต่เวอร์ชัน 2.2 ดังนั้นAssert.AreEqualจะทำงานได้ดี
AJ Richardson

คำตอบ:


141

Assert.Equalsการทดสอบโดยใช้Equalsวิธีการซึ่งโดยค่าเริ่มต้นใช้ความเท่าเทียมกันในการอ้างอิงและเนื่องจากเป็นวัตถุต่างกันจึงไม่เท่ากัน คุณจะต้องเปรียบเทียบแต่ละไบต์ในอาร์เรย์และตรวจสอบว่าเท่ากัน วิธีหนึ่งในการทำเช่นนี้คือแปลงเป็นสิ่งที่ใช้ ICollection และใช้CollectionAssert.AreEqual ()แทน


3
อาร์เรย์มีอยู่แล้วICollectionแน่นอน มันเป็นIListไฟล์. สิ่งสำคัญคือ "ความเท่าเทียมกันของคอลเลกชัน" ของคุณจะพิจารณาการเรียงลำดับ (กล่าวคือคอลเลกชันต้องเท่ากันตามลำดับไม่ใช่แค่ชุดทางคณิตศาสตร์)
Jeppe Stig Nielsen

คำตอบนี้ผิด! "Assert.AreEqual ตรวจสอบว่า objectOne.Equals (objectTwo) จะคืนค่าเป็นจริง" (ดูblog.robustsoftware.co.uk/2009/05/… ) หากคุณต้องการตรวจสอบความเท่าเทียมกันในการอ้างอิงคุณต้องใช้ Assert.AreSame () ผลลัพธ์ของ Assert.AreEqual () ขึ้นอยู่กับชนิดของวัตถุ
user1027167

@ user1027167 - ชี้แจงแล้ว ในกรณีนี้เขาไม่ได้พยายามตรวจสอบความเท่าเทียมกันของการอ้างอิง แต่มีเนื้อหาเหมือนกันหรือไม่ดังนั้นฉันไม่คิดว่าคำตอบต้องการความแม่นยำขนาดนั้น
tvanfosson

2
ฉันขอแนะนำให้ดูวิธีการอื่น ๆ ของ CollectionAssert ด้วย ... ฉันใช้กรอบการทดสอบหน่วยนี้มานานแค่ไหนแล้วและไม่รู้จัก CollectionAssert! ฉันทำมันด้วยตนเองมานานเกินไปและรู้สึกโง่มาก

44

Equalsเพราะอาร์เรย์ไม่แทนที่

คุณยังไม่ได้บอกว่าคุณใช้กรอบการทดสอบใด แต่โดยพื้นฐานแล้วมันจะขึ้นอยู่กับกรอบนั้นสำหรับอาร์เรย์กรณีพิเศษ คุณสามารถใช้วิธีการช่วยเหลือของคุณเองเพื่อทำเช่นนั้นได้เสมอ ฉันเคยทำบางครั้ง สำหรับการแฮ็กที่รวดเร็วและสกปรกหากคุณใช้. NET 3.5 คุณสามารถใช้Enumerable.SequenceEqualวิธีการขยาย:

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

วิธีการช่วยเหลือแบบกำหนดเองสามารถให้รายละเอียดเพิ่มเติมเกี่ยวกับความแตกต่างของวิธีการเหล่านี้ได้ คุณอาจพบว่าวิธีการเหล่านี้มีMoreLINQ.TestExtensionsประโยชน์แม้ว่าจะค่อนข้างหยาบและพร้อมเช่นกัน


ฉันใช้การทดสอบหน่วย VSTS มีการยืนยันทางเลือกในตัวที่ฉันสามารถใช้ได้หรือทำ for-loop และเปรียบเทียบไบต์ถ้าทั้งหมดเท่ากันแล้วยืนยันหรือไม่
David Anderson

ฉันกลัวว่าจะไม่ได้ใช้การทดสอบหน่วย VSTS - แต่คำแนะนำของ tvanfosson นั้นเหมาะสม
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
ทำไมต้องแปลงไบต์ [] เป็นสตริงเพื่อทำการเปรียบเทียบ ไม่จำเป็นและลองนึกดูว่าข้อผิดพลาดอาจเกิดจากการแปลงเองไม่ใช่ไบต์ []
Luis Filipe

2

วิธีการ Assert.AreEqual ภายใต้ประทุนจะสิ้นสุดการตั้งค่าเริ่มต้นเป็น Object.Equals () สำหรับค่าที่ไม่ใช่ค่าว่าง การใช้งานตามค่าเริ่มต้นของ Object.Equals () คือความเท่าเทียมกันอ้างอิง อาร์เรย์ 2 อาร์เรย์มีค่าเท่ากัน แต่การอ้างอิงความแตกต่างอย่างชาญฉลาดและด้วยเหตุนี้จึงไม่ถือว่าเท่ากัน


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

จะเปรียบเทียบของ ... ได้ผลครับ ..


0

สร้างวิธีการช่วยเหลือง่ายๆ:

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]);
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.