2015-01-29 1 views
12

제 테스트 중 하나에서 컬렉션에 특정 항목이 있는지 확인하고자합니다. 따라서이 컬렉션을 예상 컬렉션 의 항목과 비교하려면 항목과 관련이 없습니다. 현재, 내 테스트 코드는 다음과 같이 보입니다.xunit.net에서 항목의 순서에 관계없이 두 개의 모음을 비교하는 쉬운 방법이 있습니까?

[Fact] 
public void SomeTest() 
{ 
    // Do something in Arrange and Act phase to obtain a collection 
    List<int> actual = ... 

    // Now the important stuff in the Assert phase 
    var expected = new List<int> { 42, 87, 30 }; 
    Assert.Equal(expected.Count, actual.Count); 
    foreach (var item in actual) 
     Assert.True(expected.Contains(item)); 
} 

xunit.net에서 쉽게 구현할 수있는 방법이 있습니까? 이 방법은 두 컬렉션에서 항목의 순서가 동일한 지 확인하기 위해 Assert.Equal을 사용할 수 없습니다. Assert.Collection을 살펴 보았지만 위 코드에서 Assert.Equal(expected.Count, actual.Count) 문을 제거하지 않았습니다.

미리 답변 해 주셔서 감사합니다.

답변

14

브래드 윌슨 전에 두 목록을 주문 순서에 대해 걱정하지 않는다 그렇다면 그 사람이해야 LINQ의 OrderBy 연산자와 이후 Assert.Equal을 사용하여 두 개의 컬렉션에 순서를 고려하지 않고 동일한 항목이 들어 있는지 확인하십시오. 물론, 먼저 해당 주문 클래스에 사용할 수있는 해당 항목 클래스의 속성을 가져야합니다. (필자의 경우에는 그렇지 않습니다.)

저는 개인적으로 유창한 스타일로 적용 할 수있는 많은 어설 션 방법을 제공하는 라이브러리 인 FluentAssertions을 사용하여이 문제를 해결했습니다. 물론, there are also a lot of methods that you can use to validate collections. 내 질문의 맥락에서

, 나는 다음과 같은 코드를 사용합니다 다음 BeEquivalentTo 호출이 항목의 순서를 무시하기 때문에

[Fact] 
public void Foo() 
{ 
    var first = new[] { 1, 2, 3 }; 
    var second = new[] { 3, 2, 1 }; 

    first.Should().BeEquivalentTo(second); 
} 

이 테스트를 통과한다.

Shouldly 또한 FluentAssertions와 함께하고 싶지 않은 경우 좋은 대안입니다.

7

아니 xUnit의,하지만 Linq에 응답 : xUnit의에서 그래서

bool areSame = !expected.Except(actual).Any() && expected.Count == actual.Count; 

:

Assert.True(!expected.Except(actual).Any() && expected.Count == actual.Count)); 

@ ROBI-Y로 아마 CollectionAssert.AreEquivalent

+0

에서 CollectionAssert.AreEquivalent를 사용할 수 있습니까? – aquinas

+1

목록 1이 {1, 3, 5}이고 목록 2가 {1, 3, 3, 3, 5}이면 Raph의 대답은 실패합니다. 이제는 목록 1이 {1, 1, 3, 5, 5}이고 목록 2가 {1, 3, 3, 5, 5}이면 실패 할 것이기 때문에 크기를 검사하는 것으로 충분하지 않을 수도 있습니다.그래도 Raph에 +1하면 아주 우아한 출발점이됩니다. –

+0

Except는 두 목록 간의 차이점을 산출합니다. 하나의 목록에 더 많은 항목이 있으면이 항목이 산출됩니다. 크기를 확인할 필요가 없습니다. – rducom

4

다른 방법이 Microsoft.VisualStudio.QualityTools.UnitTestFramework에 말했다, is :

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

이렇게하면 주문을 확인합니다. 이것은 내부적으로 발생하는 것입니다 :

using (IEnumerator<TSource> e1 = first.GetEnumerator()) 
     using (IEnumerator<TSource> e2 = second.GetEnumerator()) 
     { 
      while (e1.MoveNext()) 
      { 
       if (!(e2.MoveNext() && comparer.Equals(e1.Current, e2.Current))) return false; 
      } 
      if (e2.MoveNext()) return false; 
     } 
     return true; 

당신이 xunit.net이 Github Issue에서 나에게 말했다에서 불과

Assert.True(expected.OrderBy(i => i).SequenceEqual(actual.OrderBy(i => i))); 
+0

Raph - 어쩌면 제가 실제 목록에 반드시 int 값이 포함되지 않았다고 대답 했어야합니다. 사실 내가 사용하는 값은 정렬 할 수 없습니다 (즉, 해당 클래스는 'IComparable '을 구현하지 않습니다). 따라서 'SequenceEqual'은 항목 순서를 검사 할 때 옵션이 아닙니다. – feO2x

+0

클래스에 ID 속성이있는 경우이 속성을 사용하여 주문할 수 있습니다. 최악의 경우 클래스에 사용자 정의 IEqualityComparer 을 구현할 수 있습니다. – rducom

0

당신은 Microsoft

CollectionAssert.AreEquivalent(expected, actual); 
또한 잘하지만 크기를 확인해야
관련 문제