2012-10-09 19 views
7

Próbuję wykonać tdd i użyć mongodb jako bazy danych. Ale nie mogę rozwiązać problemu kpiny z mongody. Czy jest jakaś możliwość naśmiewania się z mongodb do testowania jednostkowego w .NET?Testowanie jednostek Mongodb w .NET


Aktualizacja

znalazłem bardzo dobry blog soltion czytania. Można go znaleźć here:

Odpowiedz

13

Zamiast szyderczy MongoDB, powinno być szyderczy warstwę na szczycie MongoDB.

Możesz rozważyć interfejs, który udostępnia operacje na twoim repozytorium, które są agnostyczne dla baz danych danych. Na przykład, możesz chcieć interfejs, który Abstracts operacji na Student typów, tak jak poniżej:

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

Podczas tworzenia innych zależności, może wstrzyknąć wystąpień powyżej interfejsu lub którykolwiek abstrakcje wyższego poziomu wybrać.

Chodzi o to, nie należy wystawiać MongoDB bezpośrednio.

Gdy to zrobisz, możesz sfałszować stworzone interfejsy, mając jedną implementację do testowania przeciwko fałszywej implementacji, a następnie rzeczywistą implementację z własnymi testami, aby sprawdzić, czy operacje na implementacji są poprawne, gdy podstawowa implementacja jest z MongoDB.

Chociaż zdecydowanie jest to possible to mock most of MongoDB's classes (as the methods are virtual), zyskujesz na tym, że jesteś agnostykiem wytrwałości; Jeśli chcesz przełączyć na CouchDB lub elastyczne wyszukiwanie, nie musisz zmieniać wywołań tych interfejsów, po prostu utworzymy nową implementację.


Ponieważ you are trying to test the implementation of the repository, to są na ogół dobrze, jak już wspomniano wcześniej, większość funkcji MongoDB są virtual, który jest przyjazny dla większości bibliotek drwiących.

To powiedziawszy, trzeba się upewnić, że zdasz MongoDatabasedo repozytorium (nie tworzyć go w repozytorium) tak, że w badaniach jednostkowych, można utworzyć odpowiedni mock a następnie przekazać do swojej implementacji repozytorium do testowania.

+0

Chociaż zgadzam się z casperOne, że będzie możliwe jest wyśmiewanie klas sterowników MongoDB za pomocą większości szyderczych frameworków, ponieważ metody publiczne są wirtualne. – kfuglsang

+0

Będę używał wzorca repozytorium. W związku z tym muszę udawać wszystkich, oszczędzać i innych. Właśnie dlatego potrzebuję makiety mongo – F0rc0sigan

+0

@kfuglsang Zaktualizowana odpowiedź z korzyściami nie kpiącymi bezpośrednio z MongoDB. – casperOne

2

Zobacz ten podobny pytanie: Mocking database in node.js?

w skrócie, szydząc MongoDB nie jest właściwe podejście. Naśmiewanie się z repozytorium jest wystarczające do testowania własnych jednostek, ale nadal musisz przetestować na MongoDB, jeśli chcesz się upewnić, że używasz go poprawnie, lub jeśli polegasz na ograniczeniach unikalności itp.

1

Ty potrzebujesz warstwy repozytorium/DAL, aby ukryć szczegóły implementacji.Coś takiego:

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); 
} 
  • Dla kodu produkcyjnego, implementować interfejs z operacjami Mongo db przy pomocy C# kierowcy
  • Dla jednostkowych kodów testowych, drwić interfejs z kolekcji w pamięci

Wygląda na to, że można kpić z opcji Dodaj/Usuń/Zapisz, a częścią składową jest funkcja zapytania. Na szczęście, ponieważ sterownik mongo C# obsługuje wyrażenia LINQ, możemy użyć LINQ jako języka zapytań, a nie na nowo odkrywać koła.

Na przykład, kod produkcyjny może wyglądać następująco:

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

i sprzętem kodu testu (jeśli się z Shim, test 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>    
}