2013-11-25 15 views
18

Recentemente ho utilizzato la libreria Hamcrest per scrivere alcuni test e ho avuto abbastanza successo, ma ora ho bisogno di fare qualcosa di più complesso e ho iniziato a vedere molte difficoltà. Devo inpsect e verificare le proprietà degli elementi in una mappa. Il mio codice di produzione è simile al seguente:Come utilizzare Hamcrest per ispezionare gli elementi della mappa

Map<String, List<MyItem>> map = new HashMap<String, List<MyItem>>(); 
    map.put("one", Arrays.asList(new MyItem("One"))); 
    map.put("two", Arrays.asList(new MyItem("Two"))); 
    map.put("three", Arrays.asList(new MyItem("Three"))); 

Desidero scrivere alcuni codici di test come il seguente, ma non viene compilato. Sembra che hasEntry di Hamcrest sia di tipo parametrizzato, mentre hasItem e hasProperty si aspettano solo Object.

assertThat(map, Matchers.<String, List<MyItem>>hasEntry("one", hasItem(hasProperty("name", is("One"))))); 

mio IDE (Eclipse) sta dando questo messaggio di errore: Il metodo con parametri di tipo <String, List<HamcrestTest.MyItem>>hasEntry(String, List<HamcrestTest.MyItem>)Matchers non è applicabile per gli argomenti (String, Matcher<Iterable<? super Object>>). Per una cosa penso che Eclipse sia confuso di quale metodo hasEntry volessi usare, dovrebbe essere hasEntry(org.hamcrest.Matcher<? super K> keyMatcher, org.hamcrest.Matcher<? super V> valueMatcher), non lo hasEntry(K key, V value).

Devo semplicemente rinunciare e ottenere l'articolo dalla mappa e ispezionare manualmente ogni proprietà? C'è un modo più pulito?

risposta

21

Youu potrebbe usare solo contains o containsInAnyOrder. È vero, si dovrà elencare tutti gli elementi del List in quel modo, ma funziona più pulito rispetto hasItem:

@SuppressWarnings("unchecked") 
@Test 
public void mapTest() { 
    Map<String, List<MyItem>> map = new HashMap<String, List<MyItem>>(); 
    map.put("one", asList(new MyItem("1"), new MyItem("one"))); 

    assertThat(map, hasEntry(is("one"), 
          containsInAnyOrder(hasProperty("name", is("one")), 
               hasProperty("name", is("1"))))); 
} 
+1

Non credo che questo sarà risolvere l'errore in fase di compilazione, perché il 'hasEntry' restituirà un' Matcher > 'al posto del' richiesta Matcher > ' –

+0

@JohnB: Che ci crediate o no, ma l'ho provato e funziona solo per me. – t0mppa

+1

Potrebbe non funzionare. Buona chiamata –

4

Quindi, solo per rendere questo più semplice si potrebbe provare questo ...

assertThat((Object)map, (Matcher)Matchers.hasEntry("one", hasItem(hasProperty("name", is("One"))))); 

andando a un tipo grezzo si ottiene un avvertimento, ma nessun errore di compilazione. Se ho usato questo trucco in passato, quando non voglio preoccuparmi di ottenere tutto il cast giusto per il compilatore.

Inoltre, è possibile utilizzare ItIterableContainingInOrder.containingInOrder(new MyItem("One"))). Ciò verificherà l'intero elenco e se MyItem implementa equals allora non si utilizzerà il riflesso nei test.

1

Dato @ t0mppa non ha fornito un buon esempio su come utilizzare di Hamcrest contains e containsInAnyOrder per questo , ecco un po 'di qualcosa per ottenere il vostro iniziato:

Map<Integer, String> columns = new HashMap<Integer, String>(); 
columns.put(1, "ID"); 
columns.put(2, "Title"); 
columns.put(3, "Description"); 

assertThat(columns.values(), contains("ID", "Title", "Description")); // passes 
assertThat(columns.values(), contains("ID", "Description", "Title")); // fails 
assertThat(columns.values(), containsInAnyOrder("ID", "Description", "Title")); // passes 

si noti che a differenza di hasItem e hasItems, questi funzionano solo se vengono fornite con un elenco completo di tutti i valori sarete matching contro. Vedere Hamcrest's javadocs per ulteriori informazioni.

Problemi correlati