W moim rozwiązaniu mam testy jednostkowe, które nie zależą od bazy danych, a raczej makiety i testy integracyjne, które mają zewnętrzne zależności, takie jak baza danych.

Kiedy wykonuję testy jednostkowe z mockami, używany jest LINQ to Object. Po uruchomieniu testów integracji lub rzeczywistego programu LINQ to Entities jest używany i jest bardziej rygorystyczny niż LINQ to Object.

Czy istnieje sposób replikowania ściślejszego zachowania LINQ To Object w moich testach jednostkowych?

8
Gilles 21 czerwiec 2011, 22:48

3 odpowiedzi

Najlepsza odpowiedź

Gdy logika testowana jednostkowo działa z IQueryable dostarczonym przez EF, po prostu nie można jej przetestować za pomocą testów jednostkowych, podrabiając EF. To zawsze prowadzi do przejścia z linq-to-entities na linq-to-objects. W przypadku czegoś uproszczonego prawidłowym sposobem na poradzenie sobie z tym w teście jednostkowym jest napisanie fałszywego zamiast makiety. Fake symulowałby zachowanie zależności. W tym przypadku pisanie fałszywego oznacza pisanie dostawcy EF działającego na kolekcji w pamięci w dokładnie taki sam sposób, jak prawdziwy dostawca działa z bazą danych. Pisanie takiego dostawcy to prawdopodobnie sam projekt.

W związku z tym, gdy logika zawiera zapytania linq-to-entities, zawsze należy ją przetestować za pomocą testów integracyjnych lub dokonać refaktoryzacji kodu tak, aby samo zapytanie było w oddzielnej metodzie (testowane przez testy integracyjne), a poprzednia logika była teraz zależna od klasy zawierającej Metoda zamiast na samym EF — prowadzi to do wzorca repozytorium, w którym IQueryalbe nie jest uwidaczniane, ale repozytorium udostępnia metodę dla każdego potrzebnego zapytania działającego na pewnej encji. Osobiście nie lubię tego rodzaju repozytoriów. Oto niedawna dyskusja o różnych implementacjach repozytorium.

Jeśli zdecydujesz sięużyćtestów integracyjnych zmiana bazy danych na in-memory może byćmożliwa z EFv4.1 i kodem, gdzie po prostu zmieniasz ciąg połączenia na SQL Compact 4 i to zadziała (chyba że używasz specjalnych bezpośrednich wywołań SQL lub wymagających niektóre specjalne typy SQL w mapowaniu). W przypadku EF z plikiem EDMX nie zadziała, ponieważ plik EDMX jest ściśle powiązany z dokładną wersją bazy danych. Posiadanie specjalnego EDMX tylko do testów jednostkowych nie jest opcją, ponieważ ponownie przetestowałbyś inny kod.

Oto zestaw powiązane pytania omawiające wyzwania z testowaniem jednostkowym kodu EF i repozytoriów.

6
Community 23 maj 2017, 14:52

Możesz użyć wzorca repozytorium, aby zdefiniować interfejs IRepository, w rzeczywistym kodzie można go zaimplementować przy użyciu Entity Framework, a w teście jednostkowym można użyć struktury makiety, aby zwrócić obiekty do testowania.

0
J.W. 21 czerwiec 2011, 22:53

Jeśli chcesz, aby twoje testy jednostkowe dla warstwy, która komunikuje się z bazą danych, miały rzeczywistą wartość i wszystkie zachowania jak w kodzie produkcyjnym, musisz porozmawiać z bazą danych. Można to uznać za złamanie zasady braku zależności w teście jednostkowym, ale nie ma innego sposobu, aby LINQ to Entities wykonywał swoją pracę, niż umożliwienie mu komunikowania się z prawdziwą bazą danych. Może (i prawdopodobnie powinna) być bazą danych w pamięci - zobacz na przykład jak sobie radzi Ayende to.

0
NOtherDev 21 czerwiec 2011, 23:35