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

Generics Hell - Как передать joda.DateTime в Hamcrest Matcher.greaterThan?

JodaTime имеет

public final class DateTime extends BaseDateTime {...}

который работает до

public interface ReadableInstant extends Comparable<ReadableInstant>

Hamcrest имеет

public static <T extends java.lang.Comparable<T>> org.hamcrest.Matcher<? super T>
    greaterThan(T value) {...}

Если я попробую

greaterThan(new DateTime());

то я получаю ошибку компиляции (Eclipse дает большую подсказку)

Общий метод moreThan (T) типа Matches не применим для аргументов (DateTime). Выведенный тип DateTime не является допустимым заместителем для ограниченного параметрa >

Я правильно понимаю, что подпись greaterThan должна быть

public static <T extends java.lang.Comparable<? super T>> org.hamcrest.Matcher<? super T>     
    greaterThan(T value)

? И есть ли способ подогнать их вместе с кастом к необработанному Comparable?

4b9b3361

Ответ 1

Да, мне кажется, что это была бы лучшая подпись.

Вы пытались явно указать тип сравнения?

Matchers.<ReadableInstant>greaterThan(new DateTime());

Я не верю, что вы можете вызвать его, используя статический импорт, а также, к сожалению, указать аргумент типа, но это может быть не слишком тяжелым.

Конечно, альтернативой является использование аргумента:

greaterThan((ReadableInstant) new DateTime());

У меня нет Hamcrest, но выше все было хорошо для меня, используя подпись, которую вы мне дали, в тестовом типе.

Ответ 2

Если вы используете его часто и беспокоитесь о преобразовании, вы также можете реализовать свой собственный Matcher следующим образом:

public static Matcher<AbstractPartial> isAfter(final AbstractPartial partial) {
    return new BaseMatcher<AbstractPartial>(){

        @Override
        public void describeTo(final Description description) {
            description.appendText("after partial: ").appendValue(partial);
        }

        @Override
        public boolean matches(final Object object) {
            if (object instanceof AbstractPartial) {
                return ((LocalDate) object).isAfter(partial);
            }
            return false;
        }
    };
}

И протестируйте его так:

    Set<LocalDate> dates = Sets.newHashSet(new LocalDate(2013, 1, 1), new LocalDate(2013, 1, 2), new LocalDate(
        2013, 1, 3));
    assertThat(
        CollectionUtils.isEqualCollection(filter(isAfter(new LocalDate(2013, 1, 1)), dates),
            Lists.newArrayList(new LocalDate(2013, 1, 2), new LocalDate(2013, 1, 3))), is(true));

Если вы хотите использовать DateTime вместо LocalDate, просто замените AbstractPartial на AbstractInstant в первом списке.