2012-03-28 12 views
12

Tenemos una aplicación web de n niveles que extrae datos de SQL Server. Nuestra lógica de acceso a datos devuelve un SqlDataReader, cuyos datos se utilizan para crear nuestros objetos comerciales (a.k.a objetos de transferencia de datos).Pruebas unitarias - stubbing un SqlDataReader

Deseamos construir pruebas unitarias para verificar nuestro código que interpreta los datos devueltos por estos objetos SqlDataReader para construir nuestros objetos comerciales.

Por lo tanto, parece necesario construir stubs para reemplazar los objetos SqlDataReader durante la prueba unitaria. Como probablemente sea bastante típico, nuestros objetos SqlDataReader generalmente devuelven múltiples conjuntos de registros, cada uno con múltiples filas.

  1. ¿Es esto una empresa sensata?
  2. ¿Cómo debemos hacer para construir estos objetos?

Muchas gracias de antemano

Griff

Respuesta

24

Las pruebas automatizadas es básicamente siempre un esfuerzo razonable :)

El primer paso para poder probar esto es tener su declaración de la lógica de acceso a datos un IDataReader en lugar de un SqlDataReader - SqlDataReader implementa IDataReader, por lo que no hay problemas allí.

En las pruebas de su unidad, puede construir manualmente y llenar objetos DataTable, y llamar al dataTable.CreateDataReader() para obtener un IDataReader para pasar al objeto bajo prueba.

Editar

para proporcionar a sus pruebas con un conjunto de datos de ejemplo, me gustaría sugerir el uso de un ObjectMother para cada tabla de datos que utilice, manteniendo creación de las tablas de datos en un solo lugar dedicado. A continuación, puede poner métodos en cada clase ObjectMethod para actualizar ciertos datos de una manera fuertemente tipada. Por ejemplo:

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

... que luego se podría utilizar como esto para conseguir un lector de datos:

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

Imagina que uno de nuestros objetos IDataReader devuelve los detalles de un cliente: RS1 = datos personales; rs2 = permisos; rs3 - xxx, etc. La mayoría de las pruebas usará esto como un conjunto predeterminado de datos. Algunas pruebas pueden querer usar la mayoría de estos valores, pero anulan algunas de las propiedades en las tablas de datos. ¿Qué tan fácil es eso? Casi como herencia ... – DrGriff

+0

No estoy seguro de entender - ¿te refieres a un único lector de datos para múltiples conjuntos de resultados, o un conjunto de lectores de datos? En cualquier caso, he actualizado mi respuesta. –

+0

¿Por qué el voto a favor? Nadie...? –