AssertEquals 2 리스트는 순서를 무시합니다.
그건 정말 간단한 질문일 겁니다.그런데 구글에서 답을 찾을 수가 없어요.
문자열 목록이 2개 있다고 가정합니다.첫 번째는 "String A"와 "String B"를 포함하며, 두 번째는 "String B"와 "String A"를 포함합니다(순서의 차이를 알 수 있습니다).JUnit으로 테스트하여 동일한 Strings가 포함되어 있는지 확인하고 싶습니다.
순서를 무시하는 문자열의 동일성을 체크하는 어설션이 있습니까?예를 들어 org.junit 입니다.Assert.assertEquals가 AssertionError를 슬로우합니다.
java.lang.AssertionError: expected:<[String A, String B]> but was:<[String B, String A]>
회피책은 먼저 목록을 정렬한 후 어설션으로 전달하는 것입니다.하지만 가능한 한 심플하고 깔끔한 코드를 원합니다.
Hamcrest 1.3, JUnit 4.11, Mockito 1.9.5를 사용합니다.
당신이 햄크레스트를 사용한다고 했듯이
그래서 나는 Matchers 컬렉션 중 하나를 고를 것이다.
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()));
}
}
List.contains 를 사용할 수 있습니다.모두 JUnit의 주장으로첫 번째 목록에 두 번째 목록의 모든 요소가 포함되어 있는지 또는 두 번째 목록의 모든 요소가 포함되어 있는지 확인할 수 있습니다.
assertEquals(expectedList.size(), actualList.size());
assertTrue(expectedList.containsAll(actualList));
assertTrue(actualList.containsAll(expectedList));
힌트:
목록에 있는 중복 항목에서는 작동하지 않습니다.
2차 복잡성(목록에서 여러 번 반복)을 회피하는 솔루션이 있습니다.Apache Commons Collection Utils 클래스를 사용하여 목록의 빈도 수에 대한 각 항목의 맵을 만듭니다.그런 다음 단순히 두 맵을 비교합니다.
Assert.assertEquals("Verify same metrics series",
CollectionUtils.getCardinalityMap(expectedSeriesList),
CollectionUtils.getCardinalityMap(actualSeriesList));
Collection Utils.Equal Collection도 여기서 요구하는 것을 정확히 수행하고 있습니다.
AssertJ를 사용하면containsExactlyInAnyOrder()
또는containsExactlyInAnyOrderElementsOf()
필요한 것은 다음과 같습니다.
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.List;
public class CompareListTest {
@Test
public void compareListWithTwoVariables() {
List<String> expected = Arrays.asList("String A", "String B");
List<String> actual = Arrays.asList("String B", "String A");
Assertions.assertThat(actual)
.containsExactlyInAnyOrderElementsOf(expected);
}
@Test
public void compareListWithInlineExpectedValues() {
List<String> actual = Arrays.asList("String B", "String A");
Assertions.assertThat(actual)
.containsExactlyInAnyOrder("String A", "String B");
}
}
Collections.sort(excepted);
Collections.sort(actual);
assertEquals(excepted,actual);
파티에 늦었지만 Junit만을 사용한 해결 방법이 있습니다.어떤 생각이든 환영합니다.
List<String> actual = new ArrayList<>();
actual.add("A");
actual.add("A");
actual.add("B");
List<String> expected = new ArrayList<>();
actual.add("A");
actual.add("B");
actual.add("B");
//Step 1: assert for size
assertEquals(actual.size(), expected.size());
//Step 2: Iterate
for(String e: expected){
assertTrue(actual.contains(e));
actual.remove(e);
}
빠른 수정을 위해 두 가지 방법을 모두 확인합니다.
assertTrue(first.containsAll(second));
assertTrue(second.containsAll(first));
또, 같은 요소의 수가 다른 상황(예: 1, 1, 2, 2)에서는, false positive를 얻을 수 없었습니다.
junit-addons jar에 포함된 ListAssert를 사용할 수 있습니다.
ListAssert.assertEquals(yourList, Arrays.asList(3, 4, 5));
Roberto Izquierdo의 해는 일반적으로 2차 복잡도를 가집니다.HashSets의 솔루션에는 항상 선형 복잡성이 있습니다.
assertTrue(first.size() == second.size() &&
new HashSet(first).equals(new HashSet(second)));
다른 답변은 서드파티제의 유틸리티를 참조하고 있거나 올바르지 않거나 비효율적인 것 같습니다.
Java 8의 O(N) 바닐라 솔루션을 소개합니다.
public static void assertContainsSame(Collection<?> expected, Collection<?> actual)
{
assert expected.size() == actual.size();
Map<Object, Long> counts = expected.stream()
.collect(Collectors.groupingBy(
item -> item,
Collectors.counting()));
for (Object item : actual)
assert counts.merge(item, -1L, Long::sum) != -1L;
}
언급URL : https://stackoverflow.com/questions/22807328/assertequals-2-lists-ignore-order
'programing' 카테고리의 다른 글
SQL 구문. 올바른 구문은 MariaDB 서버 버전에 해당하는 매뉴얼을 참조하십시오. (0) | 2022.09.25 |
---|---|
특정 테이블에서 왼쪽 조인 속도가 매우 느립니다. (0) | 2022.09.23 |
쿼리 문자열 매개 변수의 Java URL 인코딩 (0) | 2022.09.22 |
왜 일부 리터럴의 경우 반환이 거짓입니까? (0) | 2022.09.18 |
Java에 Mutex가 있나요? (0) | 2022.09.18 |