Извлечение поля как из фактических, так и из ожидаемых объектов при тестировании с помощью AssertJ

Я хотел бы проверить, что список содержит подсписок другого списка. Вот фиктивный пример того, как я это делаю сейчас:

@Test
public void testExtracting() throws Exception {
    final List<User> users = new ArrayList<>();
    users.add(new User(5234, "Adam"));
    users.add(new User(4635, "David"));

    final List<User> newUsers = new ArrayList<>();
    newUsers.add(new User(6143, "Bob"));
    newUsers.add(new User(3465, "Cindy"));

    users.addAll(newUsers);

    assertThat(users).extracting("id").contains(newUsers.get(0).id, newUsers.get(1).id);
}

public static class User {
    public long id;
    public String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

Можно ли добиться того же результата более компактным способом, не переопределяя метод equals класса User? Я ищу что-то вроде:

assertThat(users).contains(newUsers.get(0), newUsers.get(1)).extracting("id");

Или еще лучше:

assertThat(users).contains(newUsers.subList(0, 2)).extracting("id");

person arekolek    schedule 05.06.2017    source источник


Ответы (1)


Если вы можете добавить метод getId() к User, вы можете решить эту проблему с помощью экстрактора:

assertThat(users)
    .extracting("id")
    .containsAll(extractProperty("id").from(newUsers));

Не имея возможности изменять User (поэтому не нужно переопределять hashcode() или equals() или добавлять геттеры), вам нужно будет извлечь id из обоих наборов и сравнить их. У меня это сработало, но я признаю, что это немного некрасиво.

assertThat(users)
    .extracting("id")
    .containsAll(newUsers.stream().map(it -> it.id).collect(Collectors.toSet()));

Я использую assertJ для извлечения идентификатора из набора пользователей и потоков / карты Java 8, чтобы получить все идентификаторы newUser в одной коллекции. Таким образом, ваша newUsers коллекция может быть сколь угодно большой, и вам не придется самостоятельно жестко кодировать отображение.

Обратите внимание, что работа с потоком / картой во втором примере такая же, как и в первом примере extractProperty, мы просто делаем это вручную.

person Todd    schedule 05.06.2017
comment
На самом деле, у меня есть геттеры, думаю, я упростил свой пример. Это был хороший улов с твоей стороны. Кроме того, меня сначала застали врасплох, потому что вы изменили contains на containsAll. Я тоже использовал doesNotContain, но у него есть аналог doesNotContainAnyElementsOf, так что я думаю, что у меня все хорошо. Спасибо! - person arekolek; 05.06.2017