2012-04-06 15 views
5

Estoy investigando bases de datos NoSQL y tengo una pregunta con respecto a las pruebas unitarias. ¿Cuál es el método apropiado para probar la lógica de negocios por unidad? ¿Cómo se burla una base de datos NoSQL?NoSQL - ¿Cómo simular la base de datos para pruebas unitarias?

+0

También podría considerar un DB en memoria para probar. –

+0

La pregunta es qué tecnología NoSQL. Muchos tienen capacidades en memoria, otros tienen sus propios trucos. Graph DB es diferente de doc DB al igual que ambos son diferentes de un RDBMS. – synhershko

+0

@synhershko - MongoDB – mtm927

Respuesta

2

Su lógica de negocio no debe tocar la base de datos directamente, sino más bien pasar por una capa de acceso a la base de datos. Esto le permite simular esa capa intermedia para pruebas unitarias. Para hacer esto, puede usar inyección de dependencia y burla. Existen marcos que pueden ayudarlo con estas dos cosas, pero también puede hacerlo a mano. He aquí un ejemplo:

Digamos que tenemos un DAL:

public class DBDataProvider: IDataProvider 
{ 
    public string getData() 
    { 
     //SQL to get data from actual database. 
    } 
} 

Como se puede ver, este implementa una interfaz para algo que proporciona los datos para su capa de negocio. Podría ser algo como esto:

public Interface IDataProvider 
{ 
    String getData(); 
} 

Su capa de negocio podría ser algo como esto:

public BusinessClass 
{ 
    private IDataProvider dataProvider; 

    public BusinessClass() 
    { 
     dataProvider = new DBDataProvider(); 
    } 

    public BusinessClass(IDataProvider provider) 
    { 
     dataProvider = provider; 
    } 

    public void doBusinessStuff() 
    { 
     dataProvider.getData(); 
     //Do something with data. 
    } 

} 

Así que ahora en su código de producción, que hará que su clase de negocios con el constructor por defecto, que se Haga automáticamente su clase con una conexión a la base de datos. Sin embargo, observe que podemos crear una BusinessClass con un IDataProvider que especifiquemos. Por lo tanto, se puede hacer un proveedor de datos "falso" sólo para las pruebas:

public class MockDataProvider: IDataProvider 
{ 
    public string getData() 
    { 
     //return some expected result that you can control, without doing a DB call. 
    } 
} 

Ahora en su prueba, puede crear un nuevo MockDataProvider, y sucedió que en el constructor para BusinessClass. Su clase de negocios ahora usará su proveedor de datos falsos, en lugar de la base de datos real.

Aquí hice todo a mano, pero te da una idea de cómo funciona esto. En la vida real, puede usar frameworks de inyección de burla y dependencia para escribir un montón de ese código para usted.

+0

Tienes razón. Me refería a DAL en lugar de BLL. – mtm927

+0

Actualizado con un ejemplo. :) – Oleksi

+0

Oleski, a) esto se considera una muy mala práctica. –

1

De la misma manera que se burla de cualquier dependencia. Escriba un contrato bonito y ordenado desde el cual los detalles de la implementación se puedan abstraer, luego simule ese contrato. Por lo general, esto se hace utilizando la capa de acceso a datos como contrato (s).
Sin entrar en detalles reales de implementación, supongamos que tiene una consulta en el método que desea probar: (nota, copié este código de un ejemplo de ravenDB, pero sé 0 sobre ravenDB, por lo que podría no compilar)

public void SomeMethod() 
{ 
    var name = "Hello"; 
    var motto = "World";      
    using (var docStore = new DocumentStore("localhost", 8080).Initialize()) 
    using (var session = documentStore.OpenSession()){ 
     session.Store(new Company { Name = name, Motto = motto });; 
     session.SaveChanges(); 
    } 
} 

que va a ser bastante difícil para burlarse/prueba, ya que requiere una base de datos en el servidor local en 8080. Ahora, si se separa esta lógica a cabo en otra clase:

public class AwesomeDAL 
    public virtual void AddCompany(string name, string motto){ 
     using (var docStore = new DocumentStore("localhost", 8080).Initialize()) 
     using (var session = documentStore.OpenSession()){ 
      session.Store(new Company { Name = name, Motto = motto });; 
      session.SaveChanges(); 
     } 
} 

y permitir la inyección de la dependencia (AwesomeDal):

public class ClassBeingTested 
{ 
    public AwesomeDal DAL { get; set; } 
    public ClassBeingTested() : this(new AwesomeDal()){} 
    public ClassBeingTested(AwesomeDal dal) 
    { 
     this.DAL = dal; 
    } 

    public void SomeMethod() 
    { 
     var name = "Hello"; 
     var motto = "World";      
     this.DAL.AddCompany(name, motto); 
    } 
} 

Y ahora puede probar el código BL de forma aislada. O puede simular excepciones de base de datos, o cualquier otra cosa que necesite probar porque su capa de acceso a datos está abstraída, y su implementación es fácilmente modificable con un marco como Moq o RhinoMocks

+0

¿Tiene un enlace a un ejemplo? Intenté buscar pero no encontré mucho. Gracias por la respuesta. – mtm927

+0

No lo haga de esa manera, utilice RavenDB.Embedded y ejecútelo en InMemory; consulte http://stackoverflow.com/questions/7533435/unit-testing-ravendb. Además, no use capas DAL/BLL con RavenDB, no tiene mucho sentido. – synhershko

0

Además de las respuestas ya publicadas (correctas), permítanme proponer una solución alternativa: ¡Use una base de datos de desarrollo real! Nada es una burla más realista que la realidad. Si lo prueba directamente, al menos sabrá que su código realmente se ejecutará.

Si puede abstraer fácilmente su base de datos, recomiendo hacerlo.

Cuestiones relacionadas