2014-04-02 4 views
41

그건 내가 믿는 정말로 간단한 질문이어야합니다. 하지만 어떻게 든 Google에서 답변을 찾을 수 없습니다.AssertEquals 2 목록 무시 명령

2 개의 문자열 목록이 있다고 가정합니다. 첫 번째 문자는 "문자열 A"와 "문자열 B"이고 두 번째 문자는 "문자열 B"와 "문자열 A" (순서가 다름)입니다. JUnit으로 테스트하여 정확히 문자열 인 이 들어 있는지 확인하십시오.

순서를 무시하는 문자열의 동일성을 검사하는 어설 션이 있습니까? 주어진 예를 들어 org.junit.Assert.assertEquals를 들어 먼저 목록을 정렬하고 다음 주장에게 전달하는 것입니다 주위

java.lang.AssertionError: expected:<[String A, String B]> but was:<[String B, String A]> 

일 AssertionError를 발생합니다. 그러나 나는 가능한 한 간단하고 깨끗한 코드를 원한다.

나는 Hamcrest 1.3, 의 JUnit 4.11, Mockito 1.9.5를 사용합니다.

+3

는'list1.removeAll (리스트 2)가'빈 list1''떠나야한다. 나는 당신이 원하는 것을 얻기 위해 이것을 기반으로 할 수 있다고 생각합니다. – SudoRahul

+3

'containsAll'과'removeAll'은리스트를 정렬하는 동안'O (n²)'이고 동등성을 테스트하는 것은'O (nlogn)'입니다. 'Collections.sort (list1); Collections.sort (list2); assertTrue (list1.equals (list2));'도 깨끗합니다. –

+1

가능한 복제본 [Hamcrest 비교 모음] (http : // stackoverflow.com/questions/21624592/hamcrest-compare-collections) – Joe

답변

40

, 내가 컬렉션 중 하나 선택할 것을

import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; 
import static org.junit.Assert.assertThat; 

public class CompareListTest { 

    @Test 
    public void compareList() { 
     List<String> expected = Arrays.asList("String A", "String B"); 
     List<String> actual = Arrays.asList("String B", "String A"); 

     assertThat("List equality without order", 
      actual, containsInAnyOrder(expected.toArray())); 
    } 

} 
+4

내 대답 http : // stackoverflow도 참조하십시오. .com/a/38262680/297710, 함 클레스트 matchers를 개선하고 containInAnyOrder를 사용하여 모든 주장에서 ".toArray()"를 피하는 방법 – yvolk

39

List.containsAll을 사용하면 첫 번째 목록에 두 번째 요소의 모든 요소가 포함되어 있는지 확인할 수 있으며 그 반대의 경우도 마찬가지입니다.

assertTrue(first.size() == second.size() && 
       first.containsAll(second) && second.containsAll(first)); 
+0

나는이 코드가 내가 생각하기에 가장 깨끗하기 때문에 받아 들인다. – kukis

+3

이 답변은 부정확하고 잘못되었습니다. – leventov

+0

이것은 어떻게 잘못 되었습니까? 그것은 나를 위해 작동합니다. – kukis

0

가 빠른 수정을 위해 나는이 두 가지를 확인합니다 :

assertTrue(first.containsAll(second)); 
assertTrue(second.containsAll(first)); 

그리고 같은 원소의 개수가 다른 상황 (예를 들어, 1, 1, 2, 1, 2와 노력, 2) 오탐 (false positive)을 얻지 못했습니다.

+1

코드가 여전히 실패합니다. 이 예제를 참조하십시오 - \t @Test \t public void test1() { \t \t리스트 list1 = Arrays.asList ("a", "a", "b"); \t \t 목록 list2 = Arrays.asList ("a", "b", "b"); \t \t Assert.assertTrue (list1.containsAll (list2)); \t \t Assert.assertTrue (list2.containsAll (list1)); \t} –

1

Roberto Izquierdo의 솔루션에는 일반적으로 2 차적인 복잡성이 있습니다. HashSets에 대한 해결 방법은 항상 선형 복잡성이있다 : 당신은 당신이 Hamcrest를 사용하는 것이 언급으로

assertTrue(first.size() == second.size() && 
     new HashSet(first).equals(new HashSet(second))); 
+1

이러한 접근 방식은 작동하지 않습니다. 첫 번째가 ("문자열 A")이고 두 번째가 ("문자열 A", "문자열 A") 인 경우에는 동일한 목록이 아닙니다. –

+0

@ZouZou 편집보기 – leventov

+4

크기를 확인할 수 없습니다. 첫 번째가''("s1", "s2", "s3", "s1")'이고 두번째가''("s2", "s1", "s3", "s2") 인 경우, 명부. –

0

당신은 junt-애드온 항아리에 제공 ListAssert을 사용할 수 있습니다 정합.

ListAssert.assertEquals(yourList, Arrays.asList(3, 4, 5)); 
7

다음은 2 차 복잡성 (목록을 여러 번 반복)을 방지하는 솔루션입니다. 이것은 Apache Commons CollectionUtils 클래스를 사용하여 목록의 빈도 계산 자체에 각 항목의 Map을 작성합니다. 그런 다음 두지도를 비교합니다.

Assert.assertEquals("Verify same metrics series", 
    CollectionUtils.getCardinalityMap(expectedSeriesList), 
    CollectionUtils.getCardinalityMap(actualSeriesList)); 

나는 또한 여기 요구되고 정확히 무엇을 주장 CollectionUtils.isEqualCollection 발견 ...

https://commons.apache.org/proper/commons-collections/apidocs/index.html?org/apache/commons/collections4/CollectionUtils.html

+0

이것은 실제로 받아 들여지는 대답이어야합니다. – leventov