Testowanie Repository

0

Ostatnio zacząłem tworzyć aplikację metodą TDD. Zastanawiam się w jaki sposób testujecie taki wzorzec Repository? U mnie interfejs Repository wygląda następująco:

 
IRepositry<T>{
void Add(T entity);
void Delete(T entity);
void Update(T entity);
List<T> GetAll();
T GetById(int id);
List<T> GetByExpression(Expression<Func<T, bool>> expression);
}

następnie implementuje poszczególne interfejsy.
O ile wiem jak sprawdzić funckje typu Get* (porównuję z mockowanym dummy setem) o tyle nie wiem czy Add/Update/Delete dobrze testuje. W ich przypadku używam metody Verify do sprawdzeina czy funkcje Add/Remove zostały wykonane oraz funckja SaveContext. W przypadku Update sprawdzam również metodę Attach, ale co jeśli element już jest z attachowany? Nie wiem jak to sprawdzić.

Korzystam z C#, Entity Framework, Moq.
Prosiłbym o jakieś porady - czy idę w dobrym kierunku.

0

To co tu wkleiłeś to nie jest repozytorium, tylko jakieś generyczne repozytorium, które może być co najwyżej wewnętrzną pomocniczą klasą dla prawdziwych repozytoriów.

Sensem istnienia repozytorium jest m.in. to, że jest to interfejs, który można sobie zamockować na potrzeby testów logiki biznesowej. W ogólności interfejsu nie da się testować, bo niby jak? W tym przypadku sens ma jedynie testowanie konkretnej implementacji repozytorium, czyli klasy, która faktycznie korzysta z EF i bazy danych... Tylko to będą testy integracyjne, nie jednostkowe.

P.S. Co ma Update do Attach?

0

Tak, jest to interfesj i implementuje go np dla klasy File. Następnie testy tworzę już dla danej klasy repozytorium

 
public class FileRepository: IRepository<File>

zatem czy takie repozytorium można testować z poziomu testów jednostkowych czy tylko jako testy integracyjne( przepływ danych w EF)?

0

No to zależy co to repozytorium robi ;] Zawsze da się zrobic testy jednostkowe, tylko czy warto? Bo jesli twoje repozytorium jedyne co robi to ma jednolinijkowe metody które wołają EF to czy jest sens? Ale jeśli musisz to mockujesz EF i weryfikujesz czy wołane są odpwiednie metody.

0

Ja, gdybym teraz pisał apkę skłaniałbym się raczej do stworzenia interfejsu dla DbContext (http://romiller.com/2012/02/14/testing-with-a-fake-dbcontext/), a nastepnie tworzenia query objecta generycznego//www.brian-driscoll.com/2012/10/just-code-generic-query-pattern.html i
https://stackoverflow.com/questions/14420276/well-designed-query-commands-and-or-specifications .

Wzorzec Repository to jest tylko dodatkowa warstwa dla tego co już jest zaimplementowane w EF. Tutaj dla prostych zapytań byś sobie tworzył instancję generycznego Query, która na wyjście miałaby zwracać to co chcesz, a w przypadku trudniejszych dziedziczył po Query i zamiast wymagać IQueryable na wejście wymagałbyś parametry, które w środku by odpowiednie zapytanie tworzyło.

Tutaj mądre głowy piszą o wyższości takiego rozwiązania:
http://lostechies.com/jimmybogard/2012/10/08/favor-query-objects-over-repositories/
http://ayende.com/blog/3955/repository-is-the-new-singleton
http://www.wekeroad.com/2014/03/04/repositories-and-unitofwork-are-not-a-good-idea/ (ale końcówka z SaveChanges już mi nie pasuje)

I tutaj implementacja czegoś takiego:
http://dotnetfiddle.net/ft9Ydh

Taka implementacja zapewnia i testowalność jednostkową (mockujesz Handle/Execute w Query) i prostotę pisania.
Była o tym dyskusja na grupie .NET na facebooku, kilka linków stamtąd jest.

1 użytkowników online, w tym zalogowanych: 0, gości: 1