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.