2011-11-01 9 views
13

JodaTime maGenerics Hell - Jak przekazać joda.DateTime do Hamcrest Matcher.greaterThan?

public final class DateTime extends BaseDateTime {...} 

który pracuje jego droga do

public interface ReadableInstant extends Comparable<ReadableInstant> 

Hamcrest ma

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

Gdy próbuję

greaterThan(new DateTime()); 

następnie pojawia się błąd kompilacji (Eclipse gi największa wskazówka)

Ogólna metoda greaterThan typu Matchers nie ma zastosowania dla argumentów (DateTime). Wywnioskowaną typu DateTime nie jest prawidłową substytut parametru ograniczonego>

mam rację sądząc, że podpis greaterThan powinny być rzeczywiście

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

? I czy istnieje sposób, aby je dopasować, nie licząc odlewania do surowego Comparable?

+0

Zobacz także http://stackoverflow.com/questions/6452313/how-to-implement-a-eneric-maxcomparable--comparable-b-function-in-java –

+0

[Źródło bieżące 'OrderingComparison'] (http://code.google.com/p/hamcrest/source/browse/trunk/hamcrest-java/hamcrest-library/src/main/java/org/hamcrest/number/OrderingComparison.java) ma '> Matcher greaterThan (wartość T) '. –

+0

@ Davavandness - Powinienem powiedzieć, że patrzyłem na 1.3.0RC1, ale czy RC2 nie zmienia tylko typu powrotu? To argument, który nie jest akceptowany. –

Odpowiedz

16

Tak, wygląda na to, że będzie to lepszy podpis.

Czy próbowałeś wyraźnie określić typ porównania?

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

nie wierzę można nazwać użyciem statycznego importu, a także określenie typu argumentu, niestety - ale to nie może być zbyt dużo trudności.

Oczywiście alternatywą jest rzucić argument:

greaterThan((ReadableInstant) new DateTime()); 

nie mam Hamcrest poręczny, ale przede działało w porządku dla mnie za pomocą podpisu ci, że dał mi w rodzaju testu.

+0

Nie wiedziałem, że można "rzucić" metodę - to otwiera zupełnie nowy świat składni Java! –

+0

@Duncan Nie rzucaj metody. Określasz parametr typu metody, aby kompilator nie musiał wywnioskować go z typu argumentu. –

+0

W rzeczywistości to Matchers, nie Matcher: (Matchers. greaterThan (DateTime.now()) –

2

Jeśli używamy go często i przeszkadza konwersji, można też zaimplementować własną Matcher tak:

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; 
     } 
    }; 
} 

i przetestować go w ten sposób:

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)); 

Jeśli chcesz użyj DateTime zamiast LocalDate, po prostu zamień AbstractPartial z AbstractInstant na pierwszym zestawieniu.