2010-01-18 3 views
1

MSTEST를 사용하여 .NET의 단위 테스트에서 2 개 컬렉션의 내용을 비교하려고합니다. 사물을 간단하게 만들려면 .Sort()를 사용하지 말고 컬렉션을 반복하고 항목을 한 번에 하나씩 비교하기 위해 새롭고 멋진 .Intersect Extension 메서드를 찾았습니다.교차 확장 메서드, 대/소문자 구분이 작동하지 않습니다.

수행하여 잘 작동하는 것 같다 :

  Assert.AreEqual(expected.Count, actual.Intersect(expected).Count) 

그러나, 지금은 대소 문자를 구별 할 필요가 시험을 가지고, 그것은 나누기. Intersect의 두 번째 매개 변수 인 StringComparer.Ordinal, StringComparer.InvariantCulture 및 StringComparer.CurrentCulture를 보내려고했습니다 ... 행운을 빌어 요.

누구나 전에 경험할 수 있습니까?

감사합니다.

편집 :

Actual: 
    (0) "FOO" String 
    (1) "foo" String 
    (2) "Foo" String 
    (3) "fOo" String 
    (4) "foO" String 
    (5) "BAR" String 
    (6) "BAR" String 
    (7) "BAZ" String 
    (8) "baz" String 
    (9) "foo" String 

Expected: 

    (0) "FOO" String 
    (1) "foo" String 
    (2) "Foo" String 
    (3) "fOo" String 
    (4) "foO" String 
    (5) "BAR" String 
    (6) "BAR" String 
    (7) "BAZ" String 
    (8) "baz" String 
    (9) "foo" String 

actual.Intersect(expected, StringComparer.CurrentCulture) 

    (0) "FOO" String 
    (1) "foo" String 
    (2) "Foo" String 
    (3) "fOo" String 
    (4) "foO" String 
    (5) "BAR" String 
    (6) "BAZ" String 
    (7) "baz" String 

그것은 일치하는가 'foo는'중복 제거하는 것, 그리고 일치하는 중복 'BAZ': 여기에 데이터입니다. 어쩌면 컬렉션이 일치하는지 주장하는 더 좋은 방법이 있을까요?

_EDIT2 : Intersect()는 중복을 제거하기 때문에 이것이 문제가되는 이유입니다. CollectionAssert 클래스를 찾았습니다. 이것은 내가 필요한 것입니다! 감사! _

+0

당신이 "그것을 파괴하지"와 "운"라고, 당신은 무엇을 의미합니까 :

당신은 당신이 사용했던 수 CollectionAssert 발견되지 않았다면? "잘못 계산합니다"와 같이 "깨지다"는 뜻입니까? "똑같은 잘못된 결과가 나옵니다"와 같이 "운이 없다"는 뜻입니까? –

+0

또한 대소 문자를 구별하지 않는 제품이 올바르게 작동하는지, 그리고 우연히 정확한 수를 제공하지 않는 것이 확실합니까? –

+1

또한, 수행하려는 작업에 더 적합한 CollectionAssert 클래스를 살펴볼 수도 있습니다. –

답변

2

당신은 SequenceEqual하지 Intersect 찾고 있던 CollectionAssert.AreEqual(actual, expected)

를 사용합니다. Intersect는 두 시퀀스의 교차점을 반환합니다. 그 (것)들 사이에서 공유 된 품목. {1, 2, 3} 및 {3, 4, 5}에서 교차를 사용하면 3을 반환합니다. SequenceEqual은 false를 반환합니다.

Assert.IsTrue(actual.SequenceEqual(expected)) 
+1

답장을 보내 주셔서 감사합니다. 내가 게시 한 MSDN 의사를 살펴 봤어. 한가지 주목해야 할 것은 SequenceEqual은 참조를 비교하는 것 같다 ... 실제 값이 아니기 때문에 SequenceEqual이 IComparable을 구현하지 않고도 실패했을 것이라고 생각한다. 그래도 잘 알고있는 것이 좋다! 덕분에 다시 – dferraro

+0

@ dferraro np ... 문자열이나 int 등의 콜렉션에 대해 직접 사용할 수 있으며, 기본 동등 비교자가 주어진 유형의 값으로 사용됩니다. 커스텀 클래스의 경우, 객체 비교 방법을 결정하기 위해'IEqualityComparer'가 필요합니다. –

1

그래서 같은 IEqualityComparer 구현 :

Class StringCaseInsensitiveComparer
    Implements IEqualityComparer(Of String)
    Public Function Equals(ByVal s1 As String, ByVal s2 As String) As Boolean
        Return s1.ToLower() = s2.ToLower()
    End Function
    Public Function GetHashCode(ByVal s As String) As Integer
        Return s.GetHashCode()
    End Function
End Class

그런 다음, 교차의이 오버로드를 호출

Dim first As IEnumerable(Of TSource)
Dim second As IEnumerable(Of TSource)
Dim comparer As IEqualityComparer(Of TSource)
Dim returnValue As IEnumerable(Of TSource)

그것은 당신이 방금 만든 비교 자의 인스턴스를 전달합니다. 테스트 목적으로

+0

감사합니다 - 나는 CollectionAssert를 사용해야한다고 생각했습니다. 그러나 원래의 문제로 돌아가서 InvariantCulture와 CurrentCulture 비교자가 당신이 여기에서하고있는 것과 정확하게 일치하지 않아야합니까? 그들은 그들의 문서에서 '대소 문자를 구별합니다.'라고 말합니다. – dferraro

+0

죄송합니다. 대신 StringComparer를 사용해보십시오.InvariantCultureIgnoreCase, StringComparer.OrdinalIgnoreCase 또는 StringComparer.CurrentCultureIgnoreCase입니다. –

+0

이 문제는 대소 문자를 구분하지 않는다는 것을 깨달았습니다. 위의 데이터를 보면 intersect()가 중복을 필터링하는 것으로 보입니다. 이것이 문제입니다. – dferraro