2008-12-11 14 views
8

Ich habe Moq verwendet, um meine repositories zu verspotten. Jedoch hat jemand kürzlich gesagt, dass sie es vorziehen, hartcodierte Testimplementierungen ihrer Repository-Schnittstellen zu erstellen.Wie verspotten Sie Ihre Repositories?

Was sind die Vor- und Nachteile jedes Ansatzes?

Edit: geklärt Bedeutung des Repository mit Link zu Fowler.

Antwort

6

ich zwei Szenarien mit Repositories im Allgemeinen zu sehen. Ich frage nach etwas, und ich bekomme es, oder ich frage nach etwas, und es ist nicht da.

Wenn Sie Ihr Repository mokieren, bedeutet das, dass das System unter Test (SUT) etwas ist, das Ihr Repository verwendet. Daher möchten Sie im Allgemeinen testen, ob sich Ihr SUT korrekt verhält, wenn ihm ein Objekt aus dem Repository zugewiesen wird. Und Sie möchten auch testen, ob es die Situation richtig behandelt, wenn Sie etwas zurück bekommen und nicht, oder nicht sicher sind, ob Sie etwas zurückbekommen.

Hartcodierte Testdoppelwerte sind in Ordnung, wenn Sie Integrationstests durchführen. Angenommen, Sie möchten ein Objekt speichern und dann zurückbekommen. Dies testet jedoch die Interaktion zweier Objekte, nicht nur das Verhalten des SUT. Sie sind zwei verschiedene Dinge. Wenn Sie mit der Programmierung von Fake-Repositories beginnen, benötigen Sie für diese auch Komponententests. Andernfalls basieren Sie auf Erfolg und Misserfolg Ihres Codes auf nicht getestetem Code.

Das ist meine Meinung zu Mocking vs. Test-Doppel.

0

Ich nehme an, dass mit "Repository" meinst du eine DAO; Wenn nicht, dann gilt diese Antwort nicht.

In letzter Zeit habe ich "im Speicher" "Mock" (oder Test) Implementierungen meiner DAO, die im Grunde arbeiten von Daten (eine Liste, Karte, etc.) in den Konstruktor des Mocks gemacht. Auf diese Weise kann die Komponententestklasse beliebige Daten, die sie für den Test benötigt, einwerfen, ändern usw., ohne dass alle Komponententests, die auf dem DAO "im Speicher" arbeiten, so codiert werden müssen, dass sie die gleichen Testdaten verwenden. Ein Plus, das ich in diesem Ansatz sehe, ist, dass ich, wenn ich ein Dutzend Komponententests habe, die das gleiche DAO für ihren Test verwenden müssen (um zum Beispiel in die getestete Klasse zu injizieren), muss ich nicht Erinnern Sie sich jedes Mal an alle Details der Testdaten (wie wenn der "Schein" fest codiert wäre) - der Komponententest erstellt die Testdaten selbst. Auf der anderen Seite bedeutet dies, dass jeder Komponententest ein paar Zeilen für die Erstellung und Verkabelung seiner Testdaten ausgeben muss. aber das ist ein kleiner Nachteil für mich.

Ein Codebeispiel:

public interface UserDao { 
    User getUser(int userid); 
    User getUser(String login); 
} 

public class InMemoryUserDao implements UserDao { 

    private List users; 

    public InMemoryUserDao(List users) { 
     this.users = users; 
    } 

    public User getUser(int userid) { 
     for (Iterator it = users.iterator(); it.hasNext();) { 
      User user = (User) it.next(); 
      if (userid == user.getId()) { 
       return user; 
      } 
     } 

     return null; 
    } 

    public User getUser(String login) { 
     for (Iterator it = users.iterator(); it.hasNext();) { 
      User user = (User) it.next(); 
      if (login.equals(user.getLogin())) { 
       return user; 
      } 
     } 

     return null; 
    } 
} 
+0

Ich meine das Repository-Muster. Ich habe die Frage mit einem Link zu Martin Fowlers Definition bearbeitet. –

6

SCNR: „Du nennst dich ein Repository Ich habe mit mehr Kapazität gesehen Streichholzschachteln“

+0

Das ist das erste, woran ich gedacht habe, als ich die Frage gelesen habe :-) – Ferruccio

+1

Vielen Dank für diese Antwort. Es hat mir die Mühe erspart. –