2012-03-28 16 views
12

Abbiamo un'applicazione web a più livelli che estrae i dati da SQL Server. La nostra logica di accesso ai dati restituisce un SqlDataReader i cui dati vengono quindi utilizzati per creare i nostri oggetti Business (a.k.a. Oggetti di trasferimento dati).Test unità - stubing un SqlDataReader

Vogliamo creare test unitari per verificare il nostro codice che interpreta i dati restituiti da questi oggetti SqlDataReader per creare i nostri oggetti Business.

Sembra quindi necessario creare stub per sostituire gli oggetti SqlDataReader durante il test dell'unità. Come è probabilmente abbastanza tipico, i nostri oggetti SqlDataReader in genere restituiscono più recordset, ciascuno con più righe.

  1. È uno sforzo ragionevole?
  2. Come dovremmo andare a costruire questi oggetti stub?

Molte grazie in anticipo

Griff

risposta

24

testing automatizzato è fondamentalmente sempre uno sforzo ragionevole :)

Il primo passo per essere in grado di testare questo è di avere il ritorno logica di accesso ai dati un IDataReader invece di uno SqlDataReader - SqlDataReader strumenti IDataReader, quindi nessun problema lì.

Nei test delle unità è quindi possibile creare manualmente e popolare gli oggetti DataTable e chiamare dataTable.CreateDataReader() per ottenere un IDataReader da passare nell'oggetto in prova.

Modifica

Per fornire i test con un set di dati di esempio, io suggerirei utilizzando un ObjectMother per ogni tabella di dati si utilizza, mantenendo creazione delle tabelle di dati in un unico luogo dedicato. È quindi possibile inserire metodi su ciascuna classe ObjectMethod per aggiornare determinati dati in modo fortemente tipizzato. Per esempio:

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(); 
    } 
} 

... che si potrebbe poi utilizzare come questo per ottenere un lettore di dati:

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

Immaginate che uno dei nostri oggetti IDataReader restituisce i dettagli di un cliente: RS1 = dati personali; rs2 = permessi; rs3 - xxx ecc. La maggior parte dei test userà questo come un insieme predefinito di dati. Alcuni test potrebbero voler utilizzare la maggior parte di questi valori, ma sovrascrivere alcune proprietà nei datatables. Quanto è facile? Quasi come l'ereditarietà ... – DrGriff

+0

Non sono sicuro di capire - vuoi dire un singolo lettore di dati per più set di risultati, o un insieme di lettori di dati? In ogni caso, ho aggiornato la mia risposta. –

+0

Perché il downvote? Chiunque ...? –