2017-09-17 2 views
2

두 문자열 배열 목록을 비교하는 단위 테스트를 만들려고합니다. 두 목록 비교 <string[]> 개체 C# 단위 테스트

나는 똑같은 List<string[]> 두 개체를 만드는 시도,하지만 난 CollectionAssert.AreEqual(expected, actual);를 사용하는 경우, 테스트가 실패 : 나는 또한 Assert.IsTrue(expected.SequenceEqual(actual));을 시도했습니다

[TestMethod] 
public void TestList() 
{ 
    List<string[]> expected = new List<string[]> { 
     new string[] { "John", "Smith", "200" }, 
     new string[] { "John", "Doe", "-100" } 
    }; 

    List<string[]> actual = new List<string[]> { 
     new string[] { "John", "Smith", "200" }, 
     new string[] { "John", "Doe", "-100" } 
    }; 

    CollectionAssert.AreEqual(expected, actual); 
} 

하지만, 그뿐만 아니라 실패합니다.

두 개의 문자열 목록 또는 두 개의 문자열 배열을 비교할 때이 두 가지 방법이 모두 작동하지만 두 개의 문자열 배열 목록을 비교할 때 작동하지 않습니다.

배열 문자열 값 대신 개체 참조의 두 목록을 비교하기 때문에이 방법이 실패했다고 가정합니다.

두 개의 List<string[]> 개체를 비교하여 실제로 동일한지를 어떻게 알 수 있습니까?

+2

이 시도 :.'expected.Zip을 (실제, (예, A) => e.SequenceEqual의 (a)) 모든 (당신이 그것을 호출 할 때 요소는, 당신은 IComparer를 전달하여 해당 작업을 수행 할 수 있습니다 x => x)'. – Enigmativity

+0

호기심에서 ... 같은 요소를 가지고 있지만 순서가 다른 경우 목록이 "평등"하다고 생각하십니까? 또한 문자열 배열은 객체에 대한 끔찍한 대체물이라는 점에 유의할 필요가 없습니다. – David

+0

@David이 특정 테스트에서는 엘리먼트가 같은 순서로 있어야하고 순서를 무시하는 솔루션이 필요하다는 것은 괜찮습니다. 그리고 객체가 일반적으로 문자열 배열보다 낫다는 것에 동의합니다. 이 코드는 더 큰 그림의 일부이며이 형식이어야합니다. –

답변

3

목록의 항목 객체 (string[])이기 때문에 그것은 실패하면 CollectionAssert.AreEqual 그것을 참조를 비교하는 기본 동작으로 다시 떨어지는 두 시퀀스의 요소를 비교하는 방법을 지정하지 않았기 때문에.

var first = new string[] { "John", "Smith", "200" }; 
var second = new string[] { "John", "Smith", "200" }; 

List<string[]> expected = new List<string[]> { first, second}; 
List<string[]> actual = new List<string[]> { first, second}; 

것은 어떻게 비교하는 CollectionAssert.AreEqual 말할 필요 참조 비교를 방지하려면 : 당신이 다음에 목록을 변경한다면, 예를 들어, 당신은 지금 두 목록이 같은 배열을 참조하기 때문에 테스트를 통과 찾을 것

CollectionAssert.AreEqual(expected, actual, StructuralComparisons.StructuralComparer); 
4

CollectionAssert.AreEqual(expected, actual);은 개체 참조를 비교하기 때문에 실패합니다. expectedactual은 다른 개체를 나타냅니다.

Assert.IsTrue(expected.SequenceEqual(actual)); 같은 이유로 실패합니다. 이번에는 expectedactual의 내용이 비교되지만 요소 자체는 다른 배열 참조입니다.

어쩌면 SelectMany를 사용하여 두 시퀀스를 평평하게하려고 : Enigmativity가 제대로 자신의 의견에 주목

var expectedSequence = expected.SelectMany(x => x).ToList(); 
var actualSequence = actual.SelectMany(x => x).ToList(); 
CollectionAssert.AreEqual(expectedSequence, actualSequence); 

으로 SelectMany 때 배열의 수 및/또는 요소가 다르지만, 긍정적 인 결과를 제공 할 수 있습니다 목록을 평평하게하면 같은 수의 요소가됩니다. 이 배열에 항상 같은 수의 배열과 요소가있는 경우에만 안전합니다.

+0

당신은 객체 레퍼런스에 대한 설명과 함께 그것을 만들었지 만,'.SelectMany' 접근법은 "거짓 긍정"을 한꺼번에 만들며'.Select (y => y)'에 대한 필요성이 없습니다. – Enigmativity

+0

논평. 나는 그것을 놓쳤다. 내 게시물을 편집했습니다. – Kapol

0

가장 좋은 해결책은 각 하위 모음의 항목 수와 각 하위 모음의 항목 수를 모두 확인하는 것입니다.

이 함께보십시오 :

bool equals = expected.Count == actual.Count && 
       Enumerable.Range(0, expected.Count).All(i => expected[i].Length == actual[i].Length && 
                  expected[i].SequenceEqual(actual[i])); 
Assert.IsTrue(equals); 

이는 것을 확인합니다 :

  • 을 목록 모두 같은 길이가 두 목록에서 하위 컬렉션의
  • 모든 쌍은 동일한 길이가
  • 각 하위 모음의 항목은 동일합니다.

: SelectMany을 사용하면 잘못된 항목이 생길 수 있으므로 두 번째 목록에는 같은 항목이 있지만 다른 하위 모음에는 퍼져 나올 수 있으므로 좋지 않습니다. 두 번째 목록이 동일한 하위 모음에 모두 동일한 항목이 있어도 두 목록이 동일하다고 생각합니다.