2012-10-09 54 views
7

Estoy tratando de hacer tdd y usar mongodb como base de datos. Pero no puedo resolver el problema de burlarse de mongodb. ¿Hay alguna posibilidad de burlarse de mongodb para pruebas unitarias en .NET?Mongodb unit testing in .NET


actualización

me pareció muy buen blog lectura Soltion. Se puede encontrar here:

Respuesta

13

En lugar de burlarse de MongoDB, debe burlarse de una capa en la parte superior de MongoDB.

Es posible que desee considerar una interfaz que expone las operaciones en su repositorio que son independientes del almacén de datos subyacente. Por ejemplo, es posible que desee una interfaz que abstrae a cabo operaciones en Student tipos, así:

public interface IStudentOperations 
{ 
    void Add(Student student); 
} 

Al crear otras dependencias, se inyecta instancias de la interfaz anterior, o cualquier abstracciones de alto nivel que elija.

El punto es, no exponer MongoDB directamente.

Una vez hecho esto, puede simular las interfaces que crea todo lo que desea, teniendo una implementación para probar contra la implementación simulada y luego una implementación real con sus propias pruebas para validar que las operaciones en la implementación son correctas cuando la implementación subyacente es con MongoDB.

Si bien es definitivamente possible to mock most of MongoDB's classes (as the methods are virtual), obtiene el beneficio de ser independiente de la persistencia; si quiere cambiar a decir, CouchDB o elasticsearch, no tiene que cambiar las llamadas a estas interfaces, simplemente crea una nueva implementación.


Debido you are trying to test the implementation of the repository, a continuación, son en general muy bien, como se ha dicho antes, la mayoría de las funciones de MongoDB son virtual, que es amigable con la mayoría de las bibliotecas burlones.

Dicho esto, usted tiene que asegurarse de que se pase el MongoDatabase en su repositorio (no crearlo en el repositorio) para que en sus pruebas de unidad, puede crear la maqueta correspondiente y luego pasar en su implementación de repositorio para la prueba.

+0

Aunque estoy de acuerdo con casperOne, lo haría Es posible burlarse de las clases del controlador MongoDB con la mayoría de los frameworks de burla ya que los métodos públicos son virtuales. – kfuglsang

+0

Usaré un patrón de repositorio. SO, necesito burlarme de All, Save y otros. Es por eso que necesito un mongo falso – F0rc0sigan

+0

@kfuglsang Respuesta actualizada con los beneficios de no burlarse de MongoDB directamente. – casperOne

2

Ver esta pregunta similar: Mocking database in node.js?

En resumen, burlando MongoDB no es el enfoque correcto. Burlarse de su repositorio es adecuado para probar sus propias unidades, pero igual tendrá que probarlo contra MongoDB si quiere asegurarse de que lo está utilizando correctamente, o si depende de restricciones de singularidad, etc.

1

Usted necesita un repositorio/capa DAL para ocultar los detalles de implementación.Algo como esto:

public interface IDataContext<T> 
{ 
    // Query 
    IList<T> GetAll<T>(); 
    IList<T> GetByCriteria<T>(Query query); 
    T GetByID<T>(string id); 

    // CUD 
    void Add(T item); 
    void Delete(T item); 
    void Save(T item); 
} 
  • Para el código de producción, implementar la interfaz con las operaciones de MongoDB con la ayuda de C# conductor
  • Para los códigos de prueba de unidad, se burlan de la interfaz con una colección en memoria

Parece sencillo simular Agregar/Eliminar/Guardar, y la parte intersting es la función de consulta. Afortunadamente, dado que el controlador mongo C# admite expresiones LINQ, podemos usar LINQ como lenguaje de consulta en lugar de reinventar las ruedas.

Por ejemplo, el código de producción puede verse como:

// collection is a MongoCollection<T> object 
var items = collection.AsQueryable().Where(...linq expression...); 

Y unidad de código de prueba (si vas con Shim, prueba MS):

using (ShimsContext.Create()) 
{     
    ShimLinqExtensionMethods.AsQueryableOf1MongoCollectionOfM0(
     (MongoCollection<T> x) => Fake_DB_Collection.AsQueryable()); 
    // After this, the above "collection.AsQueryable()" will be mocked as 
    // an in-memory collection, which can be any subclass of IEnumerable<T>    
}