Stub / creazione di un database in .Net

Ho un webservice che fondamentalmente esegue solo alcune stored procedure, trasforma i dati e li invia al browser. Nessun elaboratore ORM di fantasia o qualcosa del genere coinvolto. Per essere in grado di scrivere test senza accedere al database, ho fatto quanto segue:

  • Ho estratto tutte le chiamate al DB in una class. I metodi restituiscono solo gli oggetti DataSet e DataTable.
  • Eseguita una chiamata di esempio per ciascun metodo e serializzato il DataSet / DataTable su disco.
  • Estratto un’interfaccia che espone tutti i metodi disponibili.
  • Implementata una class di database falsa che carica solo i dati serializzati e li restituisce.

Ora ho serializzato i risultati del campione che posso controllare con il mio progetto, e posso usare il database falso nei miei test.

Questo funziona abbastanza bene per me. C’è qualche framework che rende più facile la creazione e il caricamento dei dati di esempio? Il mio progetto attuale è piccolo, ma utilizzerei lo stesso schema in progetti più grandi.

Aggiornare:

Ovviamente tutte le risposte non sono sbagliate, ma manca il punto. Sono a conoscenza delle basi del test unitario. Ma il mio codice funziona con DataTables, quindi dovrei in qualche modo fingere i miei DataTable. Costruire una DataTable da zero non è un compito facile, e gonfierà i miei test e ridurrà la leggibilità. Nel mio caso, sarebbe praticamente imansible generare dati di esempio utili a mano.

Pertanto, ho eseguito alcune chiamate di esempio su un database di esempio per ottenere alcuni DataTable. Ho serializzato queste tabelle su disco e uso le versioni serializzate per creare i miei falsi DataTable durante il test. In questo modo i test sono indipendenti dal database.

Ci sono diverse opzioni su come strutturare il codice, per rendere più facile la deserializzazione delle tabelle. Ma quelli sono dettagli di implementazione che non hanno bisogno di una discussione a questo punto. Il mio problema è il seguente:

Gestire le chiamate di esempio e (de) serializzare le tabelle è un lavoro noioso. Stavo cercando alcuni strumenti per renderlo più facile.

Dalla lettura delle altre risposte e dei vari commenti che hai fatto, sembra che tu voglia un modo più semplice per generare set di dati popolati di grandi dimensioni per test di integrazione che non colpiscano il database.

NBuilder è una grande libreria open source che ho creato con successo grandi quantità di dati di test. È sufficiente combinare NBuilder, alcune classi di oggetti POCO di base e alcune riflessioni: avrai a disposizione moltissimi databili che puoi combinare facilmente in set di dati in pochissimo tempo:

public class Person { public string First { get; set; } public string Last { get; set; } public DateTime Birthday { get; set; } } private DataTable GenerateDataTable(int rows) { var datatable = new DataTable(typeof(T).Name); typeof(T).GetProperties().ToList().ForEach( x => datatable.Columns.Add(x.Name)); Builder.CreateListOfSize(rows).Build() .ToList().ForEach( x => datatable.LoadDataRow(x.GetType().GetProperties().Select( y => y.GetValue(x, null)).ToArray(), true)); return datatable; } var dataset = new DataSet(); dataset.Tables.AddRange(new[]{ GenerateDataTable(50), GenerateDataTable(100)}); 

Per testare la trasformazione non è assolutamente necessario prendere in giro il database. Sospetto che tu abbia stretto strettamente le trasformazioni con le tue chiamate al database. Quello che vuoi fare qui è estrarre tutta la tua logica di trasformazione in una class a sé stante come la seguente:

 public static Transformations { public static DataSet TransformationA(DataSet dataSet) { //transformation logic here } public static DataSet TransformationB(DataSet dataSet) { //transformation logic here } } 

Con questo è ansible testare solo la logica delle trasformazioni passando un set di dati e quindi asserendo che il set di dati restituito ha le trasformazioni corrette applicate ad esso. Questo ti impedirà di implementare un altro archivio dati (il tuo database ‘falso’) solo a scopo di test.

Speriamo che questo aiuti

Potresti prendere in giro la tua class DataAccess con Rhinomocks e restituire un datatable fittizio. Quindi puoi testare il codice che usa questo DataTable.

 var mockedDatatable= GetMockdt(); var mocks = new MockRepository(); var dal = mocks.StrictMock(); using (mocks.Record()) { Expect.Call(dal.GetDataTableFromDatabase("", null)).Return(mockedDatatable).IgnoreArguments(); } using (mocks.Playback()) { new SomeClass(dal); } 

AGGIORNA il messaggio mockdt

 private static DataTable GetMockdt() { var dt = new DataTable(); dt.Columns.Add("pageHeader"); dt.Columns.Add("templatename"); dt.Columns.Add("pageText"); dt.Columns.Add("pageTitleBar"); dt.Columns.Add("metaDescription"); dt.Columns.Add("pageStartCode"); dt.Columns.Add("pageEndCode"); dt.Columns.Add("templateStartCode"); dt.Columns.Add("templateEndCode"); dt.Columns.Add("Author"); dt.Columns.Add("version_date"); dt.Columns.Add("pageurl"); dt.Columns.Add("type"); dt.Columns.Add("isparent"); dt.Columns.Add("pagename"); dt.Columns.Add("parentname"); dt.Columns.Add("url"); var mockRow = dt.NewRow(); mockRow["pageHeader"] = "homepage"; mockRow["pageText"] = "

home

"; mockRow["templatename"] = "home"; mockRow["pageTitleBar"] = "homepages"; mockRow["metaDescription"] = "homepages"; mockRow["pageStartCode"] = "homepages"; mockRow["pageEndCode"] = "homepages"; mockRow["templateStartCode"] = "homepages"; mockRow["templateEndCode"] = "homepages"; mockRow["Author"] = "someone"; mockRow["version_date"] = ""; mockRow["pageurl"] = "home"; mockRow["type"] = "internal"; mockRow["isparent"] = "true"; mockRow["pagename"] = "homepage"; mockRow["parentname"] = "root"; mockRow["url"] = "homepage"; dt.Rows.Add(mockRow); return dt; }

Non ci sono strumenti per fare ciò che vuoi a causa delle tue esigenze che i tuoi dati siano archiviati come DataTable e hai bisogno di dati originali dal database. La parte manuale degli strumenti è il cablaggio di ciò che punta a ciò (cioè i dati in memoria per la rappresentazione dei dati nel codice). Hai già fatto questa parte, e non è ciò che è automatizzato.

Dai un’occhiata a http://nbuilder.org/

“Che cos’è?

Tramite un’interfaccia fluida ed estensibile, NBuilder consente di creare rapidamente dati di test, assegnando automaticamente valori a proprietà e campi pubblici di tipo dei tipi di dati .NET incorporati (ad esempio, stringhe e stringhe). NBuilder ti consente di sostituire le proprietà che ti interessano utilizzando espressioni lambda. ”

Nella mia esperienza, è stato abbastanza facile eseguire test end-to-end con Fluent NHibernate. Non ci sono scuse per non usare un livello così leggero quando fa così tanto per te.

Test delle specifiche di persistenza