AssertJ: извлечение первых элементов из извлечения списка возвращает список вместо

Я пытаюсь проверить первый элемент в извлеченном списке. Однако AssertJ возвращает List вместо ожидаемого объекта из .first().

Учитывая следующий образец

public class AssertJTests
{
    @Test
    @DisplayName("Region Asia should only have one Country, Malaysia")
    public void assertRegion()
    {
        Region asia = new Region()
            .setName("Asia")
            .setCountries(Lists.newArrayList("Malaysia"));

        Consumer<Region> regionRequirement = region ->
            assertThat(region)
                .extracting(Region::getName)
                .containsOnly("Asia");

        Consumer<String> countryRequirement = country ->
            assertThat(country)
                .isEqualToIgnoringCase("Malaysia");

        assertThat(asia)
            .isInstanceOfSatisfying(Region.class, regionRequirement)
            .extracting(Region::getCountries)
            .hasSize(1)
            .first()
            .isInstanceOfSatisfying(String.class, countryRequirement);
}

    protected static class Region
    {
        private String name;

        private List<String> countries;

        List<String> getCountries()
        {
            return countries;
        }

        Region setCountries(final List<String> pCountries)
        {
            countries = pCountries;
            return this;
         }

         String getName()
         {
            return name;
         }

         Region setName(final String pName)
         {
             name = pName;
             return this;
          }
    }
}

Я ожидаю, что .first() вернет String, но вместо этого он вернул List<String>. Появилась следующая ошибка:

java.lang.AssertionError: [List check first element] Expecting: <["Malaysia"]> to be an instance of: <java.lang.String> but was instance of: <java.util.ArrayList>

person Rashidi Zin    schedule 22.05.2018    source источник


Ответы (2)


_ 1_ для Object утверждения извлекает свойства тестируемого объекта (здесь asia), что приводит к List извлеченным значениям свойств. Ваш код приводит к извлечению только одного свойства, поэтому результатом является список из одного значения, оказывается, что значение также является списком, после extracting вы в конечном итоге получаете List из одного элемента, равного asia.countries.

person Joel Costigliola    schedule 22.05.2018
comment
В идеале API мог бы предоставить extracting(Function singleExtractor), который бы возвращал значение напрямую (если добавление этого не приводит к разрешению конфликта с extracting(Function... extractors). - person Joel Costigliola; 22.05.2018
comment
Я понимаю, что извлечение countries возвращает список, но мне неясно, почему .first() также возвращает список, в то время как countries List<String> вместо List<List<String>>. - person Rashidi Zin; 23.05.2018
comment
Мне жаль. Я наконец получил его после того, как перечитал ваш отзыв. Не обращайте внимания на мой комментарий выше. - person Rashidi Zin; 23.05.2018
comment
Что ж, тот факт, что вам пришлось перечитать мой комментарий, является четким указанием на то, что API должен предоставлять extracting(Function singleExtractor), я создал github.com/joel-costigliola/assertj-core/issues/1246 для этого. - person Joel Costigliola; 23.05.2018

Вы можете утверждать, используя contains и extracting методы API.

Например:

@Test
public void oneDateShouldNotAfterAnotherDate() {
    
    Set<String> errors = ...;

    Assertions
            .assertThat(errors)
            .isNotEmpty()   
            .contains("OneDate_ShouldNot_After_AnotherDate");
    
    /*
        If you need assert specific field of object. Then:
     */
    Set<Error> errors = ...;

    Assertions
            .assertThat(errors)
            .isNotEmpty()
            .extracting("message")
            .contains("OneDate_ShouldNot_After_AnotherDate");
}
person Bhuwan Prasad Upadhyay    schedule 08.11.2020