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

Πώς να χρησιμοποιήσετε το Moq για να διευκολύνετε τις δοκιμές μονάδας στο C #

Συχνά πρέπει να γράφουμε τεστ μονάδας για κώδικα που έχει πρόσβαση σε έναν εξωτερικό πόρο, όπως μια βάση δεδομένων ή ένα σύστημα αρχείων. Εάν οι πόροι αυτοί δεν είναι διαθέσιμοι, ο μόνος τρόπος για να διασφαλιστεί ότι οι δοκιμές μπορούν να εκτελεστούν είναι η δημιουργία ψευδών αντικειμένων. Στην ουσία, αντλώντας από ψεύτικες εφαρμογές αυτών των υποκείμενων εξαρτήσεων, μπορείτε να δοκιμάσετε την αλληλεπίδραση μεταξύ της μεθόδου που δοκιμάζεται και των εξαρτήσεων της. Τρία από τα πιο δημοφιλή πλαστά πλαίσια για .Net προγραμματιστές είναι οι Rhino Mocks, Moq και NMock.

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

Ξεκινώντας με το Moq

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

Το πρώτο βήμα στη χρήση του Moq είναι να το εγκαταστήσετε έτσι ώστε να μπορείτε να το χρησιμοποιήσετε στο έργο δοκιμής μονάδας. Μπορείτε να κατεβάσετε το Moq από το GitHub και να προσθέσετε αναφορές ανάλογα με την περίπτωση. Ωστόσο, προτιμώ να εγκαταστήσω το Moq μέσω του NuGet επειδή είναι πιο εύκολο και λιγότερο πιθανό να χάσετε αναφορές. Μπορείτε να εγκαταστήσετε το Moq χρησιμοποιώντας την ακόλουθη εντολή στη γραμμή εντολών NuGet.

Εγκατάσταση πακέτου Moq

Πώς να πλαστογραφείτε διεπαφές χρησιμοποιώντας Moq

Ας ξεκινήσουμε κοροϊδεύοντας μια διεπαφή. Η σύνταξη για τη δημιουργία ψεύτικου αντικειμένου χρησιμοποιώντας την τάξη Mock δίνεται παρακάτω.

Mock mockObjectType = νέο Mock ();

Τώρα, εξετάστε την ακόλουθη διεπαφή που ονομάζεται IAuthor.

δημόσια διεπαφή IAuthor

    {

int Id {get; σειρά; }

συμβολοσειρά FirstName {get; σειρά; }

συμβολοσειρά LastName {get; σειρά; }

    }

Χρησιμοποιώντας το πλαίσιο Moq, μπορείτε να δημιουργήσετε ένα πλαστό αντικείμενο, να ορίσετε τιμές ιδιοτήτων, να καθορίσετε παραμέτρους και να επιστρέψετε τιμές στις μεθόδους κλήσεων. Το παρακάτω απόσπασμα κώδικα δείχνει πώς μπορείτε να δημιουργήσετε μια παρουσία από τη διεπαφή IAuthor χρησιμοποιώντας το Moq.

var mock = νέο Mock ();

Σημειώστε ότι η κλάση Mock ανήκει στο πλαίσιο Moq και περιέχει έναν γενικό κατασκευαστή που δέχεται τον τύπο διεπαφής που θέλετε να δημιουργήσετε. Ο Moq εκμεταλλεύεται τις εκφράσεις lambda, τους αντιπροσώπους και τα γενικά. Όλα αυτά κάνουν τη χρήση του πλαισίου πολύ διαισθητική.

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

var author = νέο Mock ();

author.SetupGet (p => p.Id). Επιστροφές (1);

author.SetupGet (p => p.FirstName). Επιστροφές ("Joydip");

author.SetupGet (p => p.LastName). Επιστροφές ("Kanjilal");

Assert.AreEqual ("Joydip", συγγραφέας.Object.FirstName);

Assert.AreEqual ("Kanjilal", συγγραφέας.Object.LastName);

Πώς να χλευάσουμε μεθόδους χρησιμοποιώντας το Moq

Ας εξετάσουμε τώρα την ακόλουθη κατηγορία που ονομάζεται άρθρο. Η κατηγορία άρθρου περιέχει μόνο μία μέθοδο που ονομάζεται GetPublicationDate, η οποία δέχεται ένα αναγνωριστικό άρθρου ως παράμετρο και επιστρέφει την ημερομηνία δημοσίευσης του άρθρου.

άρθρο δημόσιας τάξης

    {

δημόσιο εικονικό DateTime GetPublicationDate (int articleId)

        {

ρίξτε νέο NotImplementedException ();

        }

    }

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

var mockObj = νέο Mock ();
mockObj.Setup (x => x.GetPublicationDate (It.IsAny ())). Επιστροφές ((int x) => DateTime.Now);

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

Το Moq σάς επιτρέπει να επαληθεύσετε εάν κλήθηκε μια συγκεκριμένη μέθοδος ή μια ιδιότητα. Το ακόλουθο απόσπασμα κώδικα το δείχνει αυτό.

mockObj.Verify (t => t.GetPublicationDate (It.IsAny ()));

Εδώ χρησιμοποιούμε τη μέθοδο επαλήθευσης για να προσδιορίσουμε εάν κλήθηκε το GetPublicationDate στο πλαστό αντικείμενο.

Πώς να κοροϊδεύουμε τις βασικές μεθόδους κατηγορίας χρησιμοποιώντας το Moq

Εξετάστε το ακόλουθο κομμάτι κώδικα. Έχουμε δύο τάξεις εδώ - την κλάση RepositoryBase και την κλάση AuthorRepository που την επεκτείνει.

δημόσια αφηρημένη τάξη RepositoryBase

{

δημόσιο εικονικό bool IsServiceConnectionValid ()

    {

// Κάποιος κωδικός

    }

}

δημόσια τάξη AuthorRepository: RepositoryBase

{

δημόσιο κενό Αποθήκευση ()

    {

εάν (IsServiceConnectionValid ())

        {

// Κάποιος κωδικός

        }

    }

}

Ας υποθέσουμε ότι θέλουμε να ελέγξουμε εάν η σύνδεση βάσης δεδομένων είναι έγκυρη. Ωστόσο, ενδέχεται να μην θέλουμε να δοκιμάσουμε όλο τον κώδικα μέσα στη μέθοδο IsServiceConnectionValid. Για παράδειγμα, η μέθοδος IsServiceConnectionValid ενδέχεται να περιέχει κώδικα που σχετίζεται με βιβλιοθήκη τρίτων. Δεν θα θέλαμε να το δοκιμάσουμε αυτό, σωστά; Εδώ είναι που η μέθοδος CallBase στο Moq έρχεται στη διάσωση.

Σε καταστάσεις όπως αυτή, όπου έχετε μια μέθοδο στην βασική κλάση που έχει αντικατασταθεί με τον πλαστό τύπο και πρέπει να παραπλανήσετε τη βασική έκδοση της μεθόδου παράκαμψης μόνο, μπορείτε να χρησιμοποιήσετε το CallBase. Το παρακάτω απόσπασμα κώδικα δείχνει πώς μπορείτε να δημιουργήσετε ένα μερικό πλαστό αντικείμενο της κλάσης AuthorRepository, ορίζοντας την ιδιότητα CallBase σε true.

var mockObj = νέο Mock () {CallBase = true};

mockObj.Setup (x => x.IsServiceConnectionValid ()). Επιστροφές (true);

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