Programování

Hamcrest obsahující zápalky

Dokumentace Hamcrest 1.3 Javadoc pro třídu Matchers přidává další dokumentaci pro několik metod této třídy, než jaké byly k dispozici v Hamcrest 1.2. Například čtyři přetížené obsahuje metody, které mají více popisnou dokumentaci Javadoc, jak je znázorněno na dvou obrázcích porovnávací obrazovky zobrazených dále.

I když je možné zjistit, jak fungují porovnávače typu „contains“, pouhým vyzkoušením, Javadoc v Hamcrest 1.3 usnadňuje čtení jejich fungování. Většina vývojářů Java pravděpodobně myslí na chování, jako je chování String.contains (CharSequence) nebo Collection.contains (Object), když myslí na obsahuje () metoda. Jinými slovy, většina vývojářů jazyka Java pravděpodobně myslí na „obsahuje“ jako na popis toho, zda řetězec / kolekce obsahuje poskytnuté znaky / objekty mezi dalšími možnými znaky / objekty. Pro hráče Hamcrest má však „obsahuje“ mnohem konkrétnější význam. Protože dokumentace Hamcrest 1.3 je mnohem jasnější, srovnávače „obsahuje“ jsou mnohem citlivější na počet položek a pořadí položek předávaných těmto metodám.

Zde zobrazené příklady používají JUnit a Hamcrest. Zde je důležité zdůraznit, že Hamcrestův soubor JAR se musí objevit na classpath testů jednotek před souborem JUnit JAR, jinak musím použít „speciální“ soubor JUnit JAR vytvořený pro použití se samostatným Hamcrest JAR. Použití některého z těchto přístupů zabrání NoSuchMethodError a dalším chybám (suc jako org.hamcrest.Matcher.describeMismatch error) vyplývajícím z neodpovídajících verzí tříd. O této nuance JUnit / Hamcrest jsem psal v příspěvku na blogu Moving Beyond Core Hamcrest in JUnit.

Další dva snímky obrazovky označují výsledky (jak je uvedeno v NetBeans 7.3) fragmentů testovacího kódu jednotky, které ukážu později v blogu, abych předvedl Hamcrest obsahující porovnávače. Předpokládá se, že testy budou mít určité chyby (7 testů úspěšně projde a 4 testy nebudou úspěšné), aby bylo zřejmé, kde Hamcrest matchers nemusí fungovat, jak se očekává bez čtení Javadoc. První obrázek ukazuje, že prošlo pouze 5 testů, 2 testy selhaly a 4 testy způsobily chyby. Je to proto, že jsem před Hamcrestem uvedl JUnit na classpath projektu „Test Libraries“ projektu NetBeans. Druhý obrázek ukazuje očekávané výsledky, protože Hamcrest JAR se vyskytuje před JUnit JAR v classpath projektu „Test Libaries“.

Pro účely této ukázky mám k testování jednoduchou vykonstruovanou třídu. Zdrojový kód k tomu Hlavní třída je zobrazena dále.

Main.java

příklady zásilky; import java.util.Collections; import java.util.HashSet; import java.util.Set; / ** * Hlavní třída, která má být testována na jednotku. * * @author Dustin * / public class Main {/ ** Používá diamantového operátora Java 7. * / private Set strings = new HashSet (); public Main () {} public boolean addString (final String newString) {return this.strings.add (newString); } public Set getStrings () {return Collections.unmodifiableSet (this.strings); }} 

S ukázanou třídou, která má být testována, je nyní čas podívat se na sestavení některých testů založených na JUnit s pomocí Hamcrest matcherů. Testy mají konkrétně zajistit, aby byly řetězce přidány prostřednictvím třídy addString (řetězec) metoda je ve svém podkladu Soubor a přístupné přes internet getStrings () metoda. Níže ukázané metody testování jednotek ukazují, jak vhodně použít Hamcrest matchery k určení, zda jsou přidané řetězce obsaženy v podkladových materiálech třídy Soubor

Použití Hamcrest obsahuje () Matcher s Single String v Set Works

 / ** * Tento test projde, protože existuje pouze jeden řetězec, takže bude * obsahovat tento jediný řetězec a pořadí bude implicitně správné. * / @Test public void testAddStringAndGetStringsWithContainsForSingleStringSoWorks () {final Hlavní předmět = nový Main (); final boolean resultJava = subject.addString ("Java"); final Set strings = subject.getStrings (); assertThat (strings, contains ("Java")); } 

Výše uvedený test jednotky prošel, protože Soubor má v sobě pouze jeden řetězec, takže pořadí a počet řetězců testovaných pomocí obsahuje zápasové zápasy.

Používání Hamcrest obsahuje se stejným počtem prvků funguje, pokud se pořadí shoduje

 / ** * Porovnávač „obsahuje“ očekává přesné řazení, což ve skutečnosti znamená, že by neměl být * používán ve spojení s {@code Set} s. Typicky bude tato metoda * fungovat a metoda se stejným názvem a "2" na konci nebude fungovat, nebo * naopak. * / @Test public void testAddStringAndGetStringsWithContainsForMultipleStringsNotWorks1 () {final Hlavní předmět = nový Main (); final boolean resultJava = subject.addString ("Java"); final boolean resultGroovy = subject.addString ("Groovy"); final Set strings = subject.getStrings (); assertThat (řetězce, obsahuje ("Java", "Groovy")); } / ** * Porovnávač „obsahuje“ očekává přesné řazení, což ve skutečnosti znamená, že * by neměl být používán ve spojení s {@code Set} s. Typicky bude tato metoda * fungovat a metoda se stejným názvem a „1“ na konci nebude fungovat, nebo * naopak. * / @Test public void testAddStringAndGetStringsWithContainsForMultipleStringsNotWorks2 () {final Hlavní předmět = nový Main (); final boolean resultJava = subject.addString ("Java"); final boolean resultGroovy = subject.addString ("Groovy"); final Set strings = subject.getStrings (); assertThat (řetězce, obsahuje ("Groovy", "Java")); } 

Dva ukázkové jednotkové testy zobrazené výše a jejich výsledný výstup spuštění těchto testů, jak je znázorněno na předchozím snímku obrazovky, ukazují, že pokud počet argumentů obsahuje () matcher jsou stejné jako počet řetězců v testované kolekci, shoda smět práce -li testované prvky jsou v přesně stejném pořadí jako prvky v kolekci. S neuspořádaným Soubor, na tuto objednávku se nelze spolehnout, takže obsahuje () není pravděpodobné, že bude dobrým srovnávačem pro použití s ​​testem jednotky na a Soubor více než jednoho prvku.

Použití Hamcrest obsahuje s různým počtem prvků nikdy nefunguje

 / ** * Demonstrace, která obsahuje NEPRODEJE, pokud existuje jiný počet * prvků, o které se dotazuje, než obsahuje ve sbírce. * / @Test public void testAddStringAndGetStringsWithContainsNotWorksDifferentNumberElements1 () {final Hlavní předmět = nový Main (); final boolean resultJava = subject.addString ("Java"); final boolean resultGroovy = subject.addString ("Groovy"); final Set strings = subject.getStrings (); assertThat (strings, contains ("Java")); } / ** * Demonstrace, která obsahuje NEPRODEJE, pokud existuje jiný počet * prvků, o které se dotazuje, než obsahuje kolekce, i když v * jiném pořadí. * / @Test public void testAddStringAndGetStringsWithContainsNotWorksDifferentNumberElements2 () {final Hlavní předmět = nový Main (); final boolean resultJava = subject.addString ("Java"); final boolean resultGroovy = subject.addString ("Groovy"); final Set strings = subject.getStrings (); assertThat (řetězce, obsahuje ("Groovy")); } 

Jak naznačují výsledky testu JUnit, tyto dva testy jednotek nikdy neprojdou, protože počet prvků, které se testují v Soubor je menší než počet prvků v souboru Soubor. Jinými slovy to dokazuje, že obsahuje () matcher netestuje jednoduše pro daný prvek, který je v kolekci: testuje všechny přítomné zadané prvky a v uvedeném pořadí. To může být v některých případech příliš omezující, takže nyní přejdu na některé další zápasy, které Hamcrest poskytuje pro určení, zda je prvek obsažen v konkrétní kolekci.

Použití Hamcrest's containsInAnyOrder () Matcher

The containsInAnyOrder matcher není tak přísný jako obsahuje () matcher: umožňuje předání testovaných prvků v libovolném pořadí v rámci obsahující kolekce.

 / ** * Test metod addString a getStrings třídy Main pomocí Hamcrest * matcher containsInAnyOrder. * / @Test public void testAddStringAndGetStringsWithContainsInAnyOrder () {final Main subject = new Main (); final boolean resultJava = subject.addString ("Java"); final boolean resultCSharp = subject.addString ("C #"); final boolean resultGroovy = subject.addString ("Groovy"); final boolean resultScala = subject.addString ("Scala"); final boolean resultClojure = subject.addString ("Clojure"); final Set strings = subject.getStrings (); assertThat (strings, containsInAnyOrder ("Java", "C #", "Groovy", "Scala", "Clojure")); } / ** * Použijte containsInAnyOrder a ukažte, že na pořadí nezáleží, pokud * všechny zadané položky jsou v kolekci v určitém pořadí. * / @Test public void testAddStringAndGetStringsWithContainsInAnyOrderAgain () {final Main subject = new Main (); final boolean resultJava = subject.addString ("Java"); final boolean resultGroovy = subject.addString ("Groovy"); final Set strings = subject.getStrings (); assertThat (strings, containsInAnyOrder ("Java", "Groovy")); assertThat (strings, containsInAnyOrder ("Groovy", "Java")); } 

Dva testy jednotek zobrazené bezprostředně nad oběma vyhověly, přestože byly testované řetězce poskytnuty containsInAnyOrder () porovnávač v jiném pořadí, než v jakém mohou existovat pro obě kolekce. Avšak méně přísné containsInAnyOrder () matcher stále vyžaduje, aby byly předány všechny prvky obsahující kolekce. Následující test jednotky neprojde, protože tato podmínka není splněna.

 / ** * To se nezdaří, protože containsInAnyOrder vyžaduje shodu všech položek *, i když v jiném pořadí. S pouze jedním vyzkoušeným prvkem a dvěma * prvky v kolekci stále selže. Jinými slovy, na pořadí * nezáleží s containsInAnyOrder, ale všechny prvky v kolekci * stále musí být předány matcheru containsInAnyOrder, jen ne v * přesně stejném pořadí. * / @Test public void testAddStringAndGetStringsWithContainsInAnyOrderDiffNumberElements () {final Hlavní předmět = nový Main (); final boolean resultJava = subject.addString ("Java"); final boolean resultGroovy = subject.addString ("Groovy"); final Set strings = subject.getStrings (); assertThat (strings, containsInAnyOrder ("Java")); } 

Hamcrest hasItem () a hasItems () Matchers fungují jako zvuky

Jak je ukázáno v následujících dvou jednotkových testovacích metodách (obě jsou úspěšné), Hamcrest hasItem () (pro jednu položku) a hasItems (pro více položek) úspěšně testuje, zda kolekce obsahuje jednu nebo více zadaných položek bez ohledu na pořadí nebo počet zadaných položek. To opravdu funguje spíše tak, že většina vývojářů Java je zvyklá na „obsahuje“ práci při práci s řetězci a kolekcemi.

 / ** * Demonstrovat hasItem () bude také fungovat pro určení, že kolekce obsahuje * konkrétní položku. * / @Test public void testAddStringAndGetStringsWithHasItem () {final Main subject = new Main (); final boolean resultJava = subject.addString ("Java"); final boolean resultGroovy = subject.addString ("Groovy"); final Set strings = subject.getStrings (); assertThat (strings, hasItem ("Groovy")); assertThat (strings, hasItem ("Java")); } / ** * Demonstrace, která hasItems funguje pro určení, že kolekce obsahuje jednu * nebo více položek a že počet položek a pořadí položek * není při určování úspěšnosti / selhání významný. * / @Test public void testAddStringAndGetStringsWithHasItems () {final Main subject = new Main (); final boolean resultJava = subject.addString ("Java"); final boolean resultGroovy = subject.addString ("Groovy"); final Set strings = subject.getStrings (); assertThat (strings, hasItems ("Groovy", "Java")); assertThat (strings, hasItems ("Java", "Groovy")); assertThat (strings, hasItems ("Groovy")); assertThat (strings, hasItems ("Java")); } 

Hamcrest isIn () Matcher testuje zadržení z jiného směru

Právě diskutované hasItem () a hasItems () dohazovači jsou méně přísní než obsahuje () a ještě méně přísné než containsInAnyOrder () a jsou často tím, co chce, když chce jednoduše zajistit, aby jedna nebo více položek bylo někde v kolekci bez obav o pořadí položek v této kolekci nebo o tom, že v této kolekci jsou další možné položky. Jedním dalším způsobem, jak použít Hamcrest k určení stejného vztahu, ale z opačné perspektivy, je použít isIn dohazovač. The isIn matcher určuje, zda je položka někde s kolekcí poskytnutou matcheru bez ohledu na pořadí této položky v kolekci nebo zda jsou nebo nejsou v této obsahující kolekci další položky.

 / ** * Použijte isIn matcher k otestování jednotlivých prvků v poskytované kolekci. * / @Test public void testAddStringAndGetStringsWithIsIn () {final Main subject = new Main (); final boolean resultJava = subject.addString ("Java"); final boolean resultGroovy = subject.addString ("Groovy"); final Set strings = subject.getStrings (); assertThat ("Groovy", isIn (strings)); assertThat ("Java", isIn (strings)); } 
$config[zx-auto] not found$config[zx-overlay] not found