Tại sao Assert.AreEqual (T obj1, Tobj2) không thành công với các mảng byte giống hệt nhau


86

Tôi có hai mảng byte giống hệt nhau trong đoạn mã sau:

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

Cả hai mảng đều giống hệt nhau đến từng byte. Trong trường hợp này, tại sao Assert.AreEqual lại thất bại?


1
Lưu ý, nếu bạn sử dụng NUnit, so sánh giá trị của các mảng được hỗ trợ kể từ phiên bản 2.2, vì vậy Assert.AreEqualsẽ hoạt động tốt.
AJ Richardson

Câu trả lời:


141

Assert.Equalskiểm tra bằng cách sử dụng Equalsphương pháp, theo mặc định sử dụng bình đẳng tham chiếu và vì chúng là các đối tượng khác nhau nên chúng không bằng nhau. Bạn sẽ muốn so sánh từng byte trong mảng và xác minh rằng chúng bằng nhau. Một cách để làm điều này là chuyển đổi chúng thành một cái gì đó thực hiện ICollection và sử dụng CollectionAssert.AreEqual () để thay thế.


3
Tất nhiên, một mảng đã là một ICollection. Nó thậm chí là một IList. Điều quan trọng là "bình đẳng bộ sưu tập" của bạn xem xét thứ tự (nghĩa là các bộ sưu tập phải bằng nhau dưới dạng chuỗi, không chỉ là tập toán học).
Jeppe Stig Nielsen

Câu trả lời này là sai! "Assert.AreEqual kiểm tra xem objectOne.Equals (objectTwo) sẽ trả về true." (xem blog.robustsoftware.co.uk/2009/05/… ). Nếu bạn muốn kiểm tra sự bình đẳng tham chiếu, bạn phải sử dụng Assert.AreSame (). Đầu ra của Assert.AreEqual () hoàn toàn phụ thuộc vào kiểu đối tượng.
user1027167

@ user1027167 - đã làm rõ. Trong trường hợp này, anh ấy không cố gắng kiểm tra sự bình đẳng tham chiếu nhưng liệu chúng có chứa cùng một nội dung hay không nên tôi không nghĩ rằng câu trả lời cần loại chính xác như vậy.
tvanfosson

2
Tôi cũng khuyên bạn nên xem xét các phương pháp CollectionAssert khác ... Tôi đã sử dụng khung kiểm thử đơn vị này bao lâu rồi và không biết về CollectionAssert! Tôi đã làm việc đó theo cách thủ công quá lâu và cảm thấy khá ngớ người.

44

Bởi vì mảng không ghi đè Equals.

Bạn chưa cho biết bạn đang sử dụng khung thử nghiệm nào, nhưng về cơ bản, nó sẽ phụ thuộc vào khung đó cho các mảng trường hợp đặc biệt. Tất nhiên, bạn luôn có thể triển khai phương pháp trợ giúp của riêng mình để làm điều đó. Tôi đã làm điều đó đôi khi. Để hack nhanh chóng và bẩn thỉu, nếu bạn đang sử dụng .NET 3.5, bạn có thể sử dụng Enumerable.SequenceEqualphương pháp mở rộng:

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

Tất nhiên, một phương thức trợ giúp tùy chỉnh có thể cung cấp cho bạn thêm chi tiết về sự khác biệt của chúng. Bạn có thể thấy các phương pháp MoreLINQ.TestExtensionshữu ích, mặc dù chúng cũng khá thô và sẵn sàng.


Tôi đang sử dụng các bài kiểm tra đơn vị VSTS. Có một khẳng định thay thế được tích hợp sẵn mà tôi có thể sử dụng hay thực hiện vòng lặp for và so sánh các byte, nếu tất cả chúng đều bằng nhau thì khẳng định không?
David Anderson

Tôi e rằng tôi chưa sử dụng các bài kiểm tra đơn vị VSTS - nhưng khuyến nghị của tvanfosson có vẻ phù hợp.
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
Tại sao lại chuyển đổi byte [] thành chuỗi để so sánh. Đó là không cần thiết và, hãy tưởng tượng, sai số có thể là trong việc chuyển đổi bản thân, không phải là byte []
Luis Filipe

2

Phương thức Assert.AreEqual bên dưới sẽ kết thúc mặc định thành Object.Equals () cho các giá trị không phải null. Việc triển khai mặc định của Object.Equals () là bình đẳng tham chiếu. Hai mảng có giá trị giống nhau khôn ngoan nhưng sự khác biệt tham chiếu khôn ngoan và do đó sẽ không được coi là bằng nhau.


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

sẽ so sánh những thứ ... Nó phù hợp với tôi ..


0

Đã tạo phương thức trợ giúp đơn giản:

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]);
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.