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.EqualsEquals메서드를 사용하여 테스트 합니다. 기본적으로 참조 같음을 사용하며 서로 다른 개체이므로 같지 않습니다. 배열의 각 바이트를 비교하고 동일한 지 확인해야합니다. 이를 수행하는 한 가지 방법은 ICollection을 구현하는 것으로 변환하고 대신 CollectionAssert.AreEqual ()을 사용하는 것입니다.


3
ICollection물론 배열은 이미 입니다. 심지어 IList. "컬렉션 같음"은 순서를 고려하는 것이 중요합니다 (즉, 컬렉션은 수학적 집합이 아니라 시퀀스와 같아야합니다).
— Jeppe Stig Nielsen

이 대답은 틀 렸습니다! "Assert.AreEqual은 objectOne.Equals (objectTwo)가 true를 반환하는지 확인합니다." ( blog.robustsoftware.co.uk/2009/05/… 참조 ). 참조 동등성을 확인하려면 Assert.AreSame ()을 사용해야합니다. Assert.AreEqual ()의 출력은 완전히 객체 유형에 따라 다릅니다.
— user1027167 2014-04-28

@ user1027167-명확 해졌습니다. 이 경우 그는 참조 평등을 확인하려고하지 않았지만 동일한 내용이 포함되어 있는지 여부를 확인하려고했기 때문에 대답에 그런 종류의 정확성이 필요하다고 생각하지 않았습니다.
— tvanfosson 2014

2
다른 CollectionAssert 메서드도 살펴볼 것을 권장합니다.이 단위 테스트 프레임 워크를 얼마나 오랫동안 사용해 왔지만 CollectionAssert에 대해 알려지지 않았습니다! 나는 너무 오랫동안 수동으로 해왔고 꽤 멍청하다고 느낍니다.

44

배열은 Equals.

어떤 테스트 프레임 워크를 사용하고 있는지는 말하지 않았지만, 기본적으로 특별한 경우 배열에 대한 프레임 워크에 달려 있습니다. 물론이를 수행하기 위해 항상 고유 한 도우미 메서드를 구현할 수 있습니다. 나는 때때로 그것을했다. 빠르고 더러운 해킹을 위해 .NET 3.5를 사용하는 경우 Enumerable.SequenceEqual확장 방법을 사용할 수 있습니다 .

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

물론 사용자 지정 도우미 메서드는 차이점에 대한 자세한 내용을 제공 할 수 있습니다. 방법 MoreLINQ.TestExtensions이 상당히 거칠고 준비되어 있지만 도움 이 될 수 있습니다.


VSTS 단위 테스트를 사용하고 있습니다. 내가 사용할 수있는 빌트인 대체 어설 션이 있습니까, 아니면 for 루프를 수행하고 바이트가 모두 같으면 어설 션을 비교합니까?
— 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
비교를 위해 byte []를 문자열로 변환하는 이유. 그것은 상상 불필요하며, 오류가 변환 자체가 아니라 바이트 []에있을 수
— 루이스 필리페

2

내부적으로 Assert.AreEqual 메서드는 null이 아닌 값에 대해 Object.Equals ()로 기본 설정됩니다. Object.Equals ()의 기본 구현은 참조 동등성입니다. 두 배열은 값이 동일하지만 참조가 다르므로 동일한 것으로 간주되지 않습니다.


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.