Προγραμματισμός

Hamcrest που περιέχουν ταιριαστές

Η τεκμηρίωση Hamcrest 1.3 Javadoc για την κατηγορία Matchers προσθέτει περισσότερη τεκμηρίωση για αρκετές από τις μεθόδους αυτής της τάξης από αυτές που ήταν διαθέσιμες στο Hamcrest 1.2. Για παράδειγμα, οι τέσσερις μέθοδοι υπερφόρτωσης περιέχουν πιο περιγραφική τεκμηρίωση Javadoc όπως φαίνεται στα δύο στιγμιότυπα οθόνης σύγκρισης που εμφανίζονται στη συνέχεια.

Παρόλο που κάποιος μπορεί να καταλάβει πώς λειτουργούν οι "ταιριαστές" ταιριαστές μόνο δοκιμάζοντάς τους, το Javadoc στο Hamcrest 1.3 διευκολύνει την ανάγνωση του τρόπου λειτουργίας τους. Οι περισσότεροι προγραμματιστές Java σκέφτονται πιθανώς συμπεριφορά όπως αυτή των String.contains (CharSequence) ή Collection.contains (Object) όταν σκέφτονται ένα περιέχει () μέθοδος. Με άλλα λόγια, οι περισσότεροι προγραμματιστές Java σκέφτονται πιθανώς "περιέχει" ως περιγραφή εάν το String / Collection περιέχει τους παρεχόμενους χαρακτήρες / αντικείμενα μεταξύ άλλων πιθανών χαρακτήρων / αντικειμένων. Ωστόσο, για τους παίκτες του Hamcrest, το "περιέχει" έχει πολύ πιο συγκεκριμένη σημασία. Καθώς η τεκμηρίωση του Hamcrest 1.3 καθιστά πολύ πιο σαφή, οι αντιστοιχιστές "περιέχει" είναι πολύ πιο ευαίσθητοι στον αριθμό των αντικειμένων και τη σειρά των αντικειμένων που μεταφέρονται σε αυτές τις μεθόδους.

Τα παραδείγματα που εμφανίζονται εδώ χρησιμοποιούν το JUnit και το Hamcrest. Είναι σημαντικό να τονιστεί εδώ ότι το αρχείο JAR του Hamcrest πρέπει να εμφανίζεται στο classpath των δοκιμών μονάδας πριν από το αρχείο JAR του JUnit, αλλιώς πρέπει να χρησιμοποιήσω το "ειδικό" αρχείο JUnit JAR που έχει κατασκευαστεί για χρήση με το αυτόνομο Hamcrest JAR. Χρησιμοποιώντας οποιαδήποτε από αυτές τις προσεγγίσεις αποφεύγεται το NoSuchMethodError και άλλα σφάλματα (suc as org.hamcrest.Matcher.describeMismatch error) που προκύπτουν από αναντιστοιχίες εκδόσεων τάξεων. Έχω γράψει για αυτήν την απόχρωση JUnit / Hamcrest στην ανάρτηση blog Moving Beyond Core Hamcrest στο JUnit.

Τα επόμενα δύο στιγμιότυπα οθόνης δείχνουν τα αποτελέσματα (όπως φαίνεται στο NetBeans 7.3) των αποσπασμάτων κώδικα δοκιμής μονάδας που θα δείξω αργότερα στο blog για να δείξω ταιριαστές που περιέχουν Hamcrest. Οι δοκιμές υποτίθεται ότι έχουν κάποιες αποτυχίες (7 δοκιμές περνούν και 4 δοκιμές αποτυγχάνουν) για να καταστεί προφανές όπου οι αγώνες του Hamcrest μπορεί να μην λειτουργούν όπως περιμένει κανείς χωρίς να διαβάσει το Javadoc. Η πρώτη εικόνα δείχνει μόνο 5 δοκιμές που περνούν, 2 δοκιμές απέτυχαν και 4 δοκιμές προκαλώντας σφάλματα. Αυτό συμβαίνει επειδή έχω καταχωρήσει το JUnit πριν από τον Hamcrest στο "Class Libraries" του έργου NetBeans. Η δεύτερη εικόνα δείχνει τα αναμενόμενα αποτελέσματα, επειδή το Hamcrest JAR εμφανίζεται πριν από το JUnit JAR στο μονοπάτι "Test Libaries" του έργου.

Για τους σκοπούς αυτής της επίδειξης, έχω μια απλή επινοημένη τάξη για δοκιμή. Ο πηγαίος κώδικας για αυτό Κύριος Το μάθημα εμφανίζεται στη συνέχεια.

Main.java

πακέτο dustin.example; εισαγωγή java.util.Collections; εισαγωγή java.util.HashSet; εισαγωγή java.util.Set; / ** * Κύρια τάξη προς δοκιμή μονάδας. * * @author Dustin * / δημόσια τάξη Main {/ ** Χρησιμοποιεί τον τελεστή διαμαντιών Java 7. * / private Set string = νέο HashSet (); public Main () {} public boolean addString (final String newString) {return this.strings.add (newString); } Δημόσιο σύνολο getStrings () {return Collections.unmodifiableSet (this.strings); }} 

Με το μάθημα που θα δοκιμαστεί να δείξει, είναι πλέον καιρός να εξετάσουμε την κατασκευή ορισμένων δοκιμών με βάση το JUnit με Hamcrest matchers. Συγκεκριμένα, οι δοκιμές είναι να διασφαλιστεί ότι οι χορδές προστίθενται μέσω της κατηγορίας addString (Συμβολοσειρά) η μέθοδος είναι στη βάση της Σειρά και προσβάσιμο μέσω του getStrings () μέθοδος. Οι μέθοδοι δοκιμής μονάδας που παρουσιάζονται στη συνέχεια δείχνουν πώς να χρησιμοποιήσετε κατάλληλα ταιριαστές Hamcrest για να προσδιορίσετε εάν οι πρόσθετες συμβολοσειρές περιλαμβάνονται στο υποκείμενο της κατηγορίας Σειρά

Η χρήση του Hamcrest περιέχει () Matcher με μονή χορδή στο Set Works

 / ** * Αυτή η δοκιμή θα περάσει επειδή υπάρχει μόνο μία συμβολοσειρά και έτσι θα * περιέχει αυτή την ενιαία συμβολοσειρά και η σειρά θα είναι σωστή από την άλλη. * / @Test public void testAddStringAndGetStringsWithContainsForSingleStringSoWorks () {τελικό Κύριο θέμα = νέο Κύριο (); τελικό boolean resultJava = subject.addString ("Java"); τελικό Set string = subject.getStrings (); assertThat (συμβολοσειρές, περιέχει ("Java")); } 

Η δοκιμή μονάδας που φαίνεται παραπάνω περνά επειδή το Σειρά έχει μόνο μία συμβολοσειρά και έτσι η σειρά και ο αριθμός των συμβολοσειρών δοκιμάστηκαν με το περιέχει αγώνες αντιστοιχιών.

Η χρήση του Hamcrest περιέχει με τον ίδιο αριθμό στοιχείων λειτουργεί εάν ταιριάζει με την παραγγελία

 / ** * Ο αντιστοιχιστής "περιέχει" αναμένει ακριβή παραγγελία, πράγμα που σημαίνει ότι δεν πρέπει * να χρησιμοποιείται σε συνδυασμό με το {@code Set} s. Συνήθως, είτε αυτή η μέθοδος * θα λειτουργήσει και η μέθοδος με το ίδιο όνομα και "2" στο τέλος δεν θα λειτουργήσει ή * αντίστροφα. * / @Test public void testAddStringAndGetStringsWithContainsForMultipleStringsNotWorks1 () {τελικό Κύριο θέμα = νέο Κύριο (); τελικό boolean resultJava = subject.addString ("Java"); τελικό boolean resultGroovy = subject.addString ("Groovy"); τελικό Set string = subject.getStrings (); assertThat (συμβολοσειρές, περιέχει ("Java", "Groovy")); } / ** * Ο αντιστοιχιστής "περιέχει" αναμένει ακριβή παραγγελία, πράγμα που σημαίνει ότι δεν πρέπει * να χρησιμοποιείται σε συνδυασμό με το {@code Set} s. Συνήθως, είτε αυτή η μέθοδος * θα λειτουργήσει και η μέθοδος με το ίδιο όνομα και "1" στο τέλος δεν θα λειτουργήσει ή * αντίστροφα. * / @Test public void testAddStringAndGetStringsWithContainsForMultipleStringsNotWorks2 () {τελικό Κύριο θέμα = νέο Κύριο (); τελικό boolean resultJava = subject.addString ("Java"); τελικό boolean resultGroovy = subject.addString ("Groovy"); τελικό Set string = subject.getStrings (); assertThat (συμβολοσειρές, περιέχει ("Groovy", "Java")); } 

Τα δύο παραδείγματα δοκιμών μονάδας που φαίνονται παραπάνω και η προκύπτουσα έξοδος από την εκτέλεση αυτών των δοκιμών, όπως φαίνεται στο προηγούμενο στιγμιότυπο οθόνης, δείχνουν ότι όσο ο αριθμός των ορισμάτων προς το περιέχει () Το matcher είναι ίδιο με τον αριθμό των χορδών στη συλλογή που δοκιμάζεται, τον αγώνα ενδέχεται εργασία αν τα στοιχεία που ελέγχθηκαν είναι ακριβώς στην ίδια σειρά με τα στοιχεία της συλλογής. Με μια μη ταξινομημένη Σειρά, δεν μπορεί να γίνει επίκληση αυτής της παραγγελίας περιέχει () δεν είναι πιθανό να είναι καλός συνδυασμός για χρήση με δοκιμή μονάδας σε ένα Σειρά με περισσότερα από ένα στοιχεία.

Η χρήση του Hamcrest περιέχει με διαφορετικό αριθμό στοιχείων που δεν λειτουργεί ποτέ

 / ** * Η επίδειξη που περιέχει ΔΕΝ θα περάσει όταν υπάρχει διαφορετικός αριθμός * στοιχείων που ζητούνται σχετικά με περιέχει από τη συλλογή. * / @Test public void testAddStringAndGetStringsWithContainsNotWorksDifferentNumberElements1 () {τελικό Κύριο θέμα = νέο Κύριο (); τελικό boolean resultJava = subject.addString ("Java"); τελικό boolean resultGroovy = subject.addString ("Groovy"); τελικό Set string = subject.getStrings (); assertThat (συμβολοσειρές, περιέχει ("Java")); } / ** * Η επίδειξη που περιέχει ΔΕΝ θα περάσει όταν υπάρχει διαφορετικός αριθμός * στοιχείων που ζητούνται περιέχει από ό, τι στη συλλογή ακόμη και όταν σε * διαφορετική σειρά. * / @Test public void testAddStringAndGetStringsWithContainsNotWorksDifferentNumberElements2 () {τελικό Κύριο θέμα = νέο Κύριο (); τελικό boolean resultJava = subject.addString ("Java"); τελικό boolean resultGroovy = subject.addString ("Groovy"); τελικό Set string = subject.getStrings (); assertThat (συμβολοσειρές, περιέχει ("Groovy")); } 

Όπως δείχνουν τα αποτελέσματα των δοκιμών JUnit, αυτές οι δύο δοκιμές μονάδας δεν περνούν ποτέ επειδή ο αριθμός των στοιχείων που δοκιμάζονται στο Σειρά είναι λιγότερος από τον αριθμό των στοιχείων στο Σειρά. Με άλλα λόγια, αυτό αποδεικνύει ότι το περιέχει () Το matcher δεν ελέγχει απλώς για ένα δεδομένο στοιχείο που βρίσκεται σε μια συλλογή: ελέγχει για όλα τα συγκεκριμένα στοιχεία που υπάρχουν και με την καθορισμένη σειρά. Αυτό μπορεί να είναι πολύ περιοριστικό σε ορισμένες περιπτώσεις, οπότε τώρα θα προχωρήσω σε άλλους αγώνες που παρέχει ο Hamcrest για να προσδιορίσει εάν ένα στοιχείο περιέχεται σε μια συγκεκριμένη συλλογή.

Χρήση του Hamcrest's περιέχειInAnyOrder () Matcher

ο περιέχειInAnyOrder Το matcher δεν είναι τόσο αυστηρό όσο το περιέχει () matcher: επιτρέπει να περάσουν τα δοκιμασμένα στοιχεία σε οποιαδήποτε σειρά μέσα στη συλλογή που περιέχει.

 / ** * Δοκιμή των μεθόδων addString και getStrings της κλάσης Main using Hamcrest * matcher περιέχειInAnyOrder. * / @Test public void testAddStringAndGetStringsWithContainsInAnyOrder () {final Κύριο θέμα = νέο Main (); τελικό boolean resultJava = subject.addString ("Java"); τελικό boolean αποτέλεσμαCSharp = subject.addString ("C #"); τελικό boolean resultGroovy = subject.addString ("Groovy"); τελικό boolean resultScala = subject.addString ("Scala"); τελικό boolean resultClojure = subject.addString ("Clojure"); τελικό Set string = subject.getStrings (); assertThat (συμβολοσειρές, περιέχειInAnyOrder ("Java", "C #", "Groovy", "Scala", "Clojure")); } / ** * Η χρήση περιέχειInAnyOrder και δείξτε ότι η παραγγελία δεν έχει σημασία εφόσον * όλες οι καταχωρήσεις που παρέχονται βρίσκονται στη συλλογή με κάποια σειρά. * / @Test public void testAddStringAndGetStringsWithContainsInAnyOrderAgain () {τελικό Κύριο θέμα = νέο Κύριο (); τελικό boolean resultJava = subject.addString ("Java"); τελικό boolean resultGroovy = subject.addString ("Groovy"); τελικό Set string = subject.getStrings (); assertThat (συμβολοσειρές, περιέχειInAnyOrder ("Java", "Groovy")); assertThat (συμβολοσειρές, περιέχειInAnyOrder ("Groovy", "Java")); } 

Οι δοκιμές δύο μονάδων που εμφανίζονται ακριβώς πάνω από τα δύο περνούν παρά τις δοκιμαστικές χορδές που παρέχονται στο περιέχειInAnyOrder () matcher με διαφορετική σειρά από αυτό που θα μπορούσαν να υπάρχουν και στις δύο συλλογές. Ωστόσο, το λιγότερο αυστηρό περιέχειInAnyOrder () Το matcher εξακολουθεί να απαιτεί να καθοριστούν όλα τα στοιχεία της συλλογής που περιέχει. Η ακόλουθη δοκιμή μονάδας δεν περνά επειδή δεν πληρούται αυτή η συνθήκη.

 / ** * Αυτό θα αποτύχει επειδή το περιέχειInAnyOrder απαιτεί όλα τα στοιχεία να ταιριάζουν * ακόμη και αν σε διαφορετική σειρά. Με τη δοκιμή μόνο ενός στοιχείου και δύο * στη συλλογή, θα αποτύχει. Με άλλα λόγια, η παραγγελία * δεν έχει σημασία με το mengandungInAnyOrder, αλλά όλα τα στοιχεία της συλλογής * πρέπει ακόμη να μεταβιβαστούν στον αγώνα αντιστοίχισης includeInAnyOrder, όχι ακριβώς με την ίδια ακριβώς σειρά. * / @Test public void testAddStringAndGetStringsWithContainsInAnyOrderDiffNumberElements () {τελικό Κύριο θέμα = νέο Κύριο (); τελικό boolean resultJava = subject.addString ("Java"); τελικό boolean resultGroovy = subject.addString ("Groovy"); τελικό Set string = subject.getStrings (); assertThat (συμβολοσειρές, περιέχειInAnyOrder ("Java")); } 

Hamcrest hasItem () και hasItems () Τα Matchers λειτουργούν ως ήχοι

Όπως φαίνεται στις επόμενες μεθόδους δοκιμής δύο μονάδων (και οι δύο περνούν), το Hamcrest hasItem () (για μεμονωμένο αντικείμενο) και hasItems (για πολλαπλά στοιχεία) ελέγχει με επιτυχία εάν μια συλλογή έχει ένα ή περισσότερα από ένα καθορισμένα αντικείμενα αντίστοιχα, χωρίς να λαμβάνεται υπόψη η παραγγελία ή ο αριθμός των συγκεκριμένων στοιχείων. Αυτό λειτουργεί πραγματικά περισσότερο όπως οι περισσότεροι προγραμματιστές Java συνηθίζουν να "περιέχουν" όταν εργάζονται με το Strings και τις συλλογές.

 / ** * Η επίδειξη hasItem () θα λειτουργήσει επίσης για τον προσδιορισμό μιας συλλογής που περιέχει * ένα συγκεκριμένο στοιχείο. * / @Test public void testAddStringAndGetStringsWithHasItem () {τελικό Κύριο θέμα = νέο Κύριο (); τελικό boolean resultJava = subject.addString ("Java"); τελικό boolean resultGroovy = subject.addString ("Groovy"); τελικό Set string = subject.getStrings (); assertThat (χορδές, hasItem ("Groovy")); assertThat (συμβολοσειρές, hasItem ("Java")); } / ** * Δείξτε ότι τα hasItems λειτουργεί για να προσδιορίσετε ότι μια συλλογή έχει ένα * ή περισσότερα αντικείμενα και ότι ο αριθμός των αντικειμένων και η σειρά των αντικειμένων * δεν είναι σημαντικός για τον προσδιορισμό της επιτυχίας / αποτυχίας. * / @Test public void testAddStringAndGetStringsWithHasItems () {τελικό Κύριο θέμα = νέο Κύριο (); τελικό boolean resultJava = subject.addString ("Java"); τελικό boolean resultGroovy = subject.addString ("Groovy"); τελικό Set string = subject.getStrings (); assertThat (συμβολοσειρές, hasItems ("Groovy", "Java")); assertThat (συμβολοσειρές, hasItems ("Java", "Groovy")); assertThat (συμβολοσειρές, hasItems ("Groovy")); assertThat (συμβολοσειρές, hasItems ("Java")); } 

Το Hamcrest isIn () Matcher Tests Containment from Other Direction

Το μόλις συζητήθηκε hasItem () και hasItems () Οι αντιστοιχιστές είναι λιγότερο αυστηροί περιέχει () και ακόμη λιγότερο αυστηρό από περιέχειInAnyOrder () και είναι συχνά αυτό που θέλει κάποιος όταν θέλει απλώς να διασφαλίσει ότι ένα ή περισσότερα αντικείμενα βρίσκονται κάπου σε μια συλλογή χωρίς να ανησυχεί για την παραγγελία του αντικειμένου σε αυτήν τη συλλογή ή ότι υπάρχουν άλλα πιθανά αντικείμενα σε αυτήν τη συλλογή. Ένας άλλος τρόπος για να χρησιμοποιήσετε το Hamcrest για να προσδιορίσετε την ίδια σχέση, αλλά από την αντίθετη προοπτική, είναι να χρησιμοποιήσετε είναι στο ταιριαστή. ο είναι στο Το matcher καθορίζει εάν ένα αντικείμενο βρίσκεται κάπου με τη συλλογή που παρέχεται στον αντιστοιχιστή χωρίς να λαμβάνεται υπόψη η παραγγελία αυτού του αντικειμένου στη συλλογή ή εάν υπάρχουν άλλα αντικείμενα σε αυτό που περιέχει τη συλλογή.

 / ** * Use isIn matcher για να ελέγξετε μεμονωμένο στοιχείο στην παρεχόμενη συλλογή. * / @Test public void testAddStringAndGetStringsWithIsIn () {τελικό Κύριο θέμα = νέο Κύριο (); τελικό boolean resultJava = subject.addString ("Java"); τελικό boolean resultGroovy = subject.addString ("Groovy"); τελικό Set string = subject.getStrings (); assertThat ("Groovy", isIn (χορδές)); assertThat ("Java", isIn (συμβολοσειρές)); } 
$config[zx-auto] not found$config[zx-overlay] not found