2012-03-28 20 views
12

Wir haben eine n-Tier-Webanwendung, die Daten von SQL Server abruft. Unsere Datenzugriffslogik gibt einen SqlDataReader zurück, dessen Daten dann verwendet werden, um unsere Geschäftsobjekte zu erzeugen (ua Datenübertragungsobjekte).Komponententests - Stubbing eines SqlDataReader

Wir möchten Komponententests erstellen, um unseren Code zu überprüfen, der die von diesen SqlDataReader-Objekten zurückgegebenen Daten zum Erstellen unserer Business-Objekte interpretiert.

Es scheint daher notwendig zu sein, Stubs zu erstellen, um die SqlDataReader-Objekte während des Komponententestens zu ersetzen. Wie es wahrscheinlich ziemlich typisch ist, geben unsere SqlDataReader-Objekte im Allgemeinen mehrere Recordsets mit jeweils mehreren Zeilen zurück.

  1. Ist das ein sinnvolles Unterfangen?
  2. Wie sollten wir diese Stub-Objekte bauen?

Vielen Dank im Voraus

Griff

Antwort

24

Automatisiertes Testen ist im Grunde immer eine sinnvolle Unterfangen :)

Ihr erster Schritt in der Lage sein, dies zu testen Ihre Rückkehr Logik Datenzugriff zu haben ist ein IDataReader statt SqlDataReader - SqlDataReader implementiert IDataReader, also keine Probleme dort.

In Ihren Unit-Tests können Sie dann manuell erstellen und DataTable Objekte bevölkern, und dataTable.CreateDataReader() rufen eine IDataReader zu bekommen in das Objekt unter Test zu bestehen.

bearbeiten

Um Ihre Tests mit einer Reihe von Beispieldaten zur Verfügung stellen, würde ich vorschlagen, ein ObjectMother für jede Datentabelle Sie verwenden, in einem speziellen Ort Erstellung der Datentabellen zu halten. Sie können dann Methoden auf jede Klasse ObjectMethod setzen, um bestimmte Daten in einer stark typisierten Weise zu aktualisieren. Zum Beispiel:

public class PersonalDetailsBuilder 
{ 
    private DataTable _dataTable; 

    public PersonalDetailsBuilder CreateNewTable() 
    { 
     this._dataTable = new DataTable("CustomerPersonalDetails") 
     { 
      Columns = new[] 
      { 
       new DataColumn("CustomerId", typeof(int)), 
       new DataColumn("CustomerName", typeof(string)) 
      } 
     }; 

     return this; 
    } 

    public PersonalDetailsBuilder AddStandardData(int numberOfRows = 3) 
    { 
     foreach (int i in Enumerable.Range(1, numberOfRows + 1)) 
     { 
      this.AddRow(i, "Customer " + i); 
     } 

     return this; 
    } 

    public PersonalDetailsBuilder AddRow(int customerId, string customerName) 
    { 
     this._dataTable.Rows.Add(customerId, customerName); 

     return this; 
    } 

    public IDataReader ToDataReader() 
    { 
     return this._dataTable.CreateDataReader(); 
    } 
} 

... die Sie dann wie folgt verwenden könnte einen Datenleser erhalten:

IDataReader customerDetailsReader = new PersonalDetailsBuilder() 
    .CreateNewTable() 
    .AddStandardData() 
    .AddRow(17, "Customer 17") 
    .ToDataReader(); 
+0

Stellen Sie sich vor, dass einer unserer IDataReader Objekte zurückgibt Informationen über einen Kunden: RS1 = persönlichen Daten; rs2 = Berechtigungen; rs3 - xxx usw. Die meisten Tests verwenden dies als Standarddatensatz. Einige Tests möchten möglicherweise die meisten dieser Werte verwenden, überschreiben jedoch einige der Eigenschaften in den Datentabellen. Wie einfach ist das? Fast wie Vererbung .... – DrGriff

+0

Ich bin nicht sicher, dass ich verstehe - meinst du einen einzelnen Datenleser für mehrere Ergebnissätze oder eine Reihe von Datenlesegeräten? Auf jeden Fall habe ich meine Antwort aktualisiert. –

+0

Warum der Downvote? Jemand...? –