Подтвердить что ты не робот

AssertEquals 2 Списки игнорируют порядок

Это должен быть действительно простой вопрос, который я считаю. Но почему-то я не могу найти ответ в Google.

Предположим, что у меня есть 2 списка строк. Сначала содержит "String A" и "String B" , второй содержит "String B" и "String A" (разница уведомлений в порядке). Я хочу проверить их с помощью JUnit, чтобы проверить, содержат ли они точно такие же строки.

Есть ли какое-либо утверждение, которое проверяет равенство строк, игнорирующих порядок? Для данного примера org.junit.Assert.assertEquals throws 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.

4b9b3361

Ответ 1

Как вы упоминаете, что вы используете Hamcrest, я бы выбрал одну из коллекции 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()));
    }

}

Ответ 2

Вы можете использовать List.containsAll с JUnit assertTrue, чтобы проверить, что первый список содержит каждый элемент из второго, и наоборот.

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

Ответ 3

Здесь решение, которое позволяет избежать квадратичной сложности (повторяя несколько раз несколько списков). Это использует класс Apache Commons CollectionUtils, чтобы создать карту каждого элемента для самого числа счетчиков в списке. Затем он просто сравнивает два Карты.

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

Ответ 4

    Collections.sort(excepted);
    Collections.sort(actual);
    assertEquals(excepted,actual);

Ответ 5

Заметим, что решение Роберто Искьердо в целом имеет квадратичную сложность. Решение на HashSet всегда имеет линейную сложность:

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

Ответ 6

Вы можете использовать ListAssert, который поставляется в jarit-аддонах jar.

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

Ответ 7

Я опаздываю на вечеринку, но здесь мое решение с использованием только 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);
}

Ответ 8

Для быстрого исправления я бы проверял оба пути:

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

И попытаться с ситуацией, когда число тех же элементов различно (например, 1, 1, 2 и 1, 2, 2), я не получил ложных срабатываний.

Ответ 9

С 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");
    }    
}