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?
3 odpowiedzi
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.
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.
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.
Podobne pytania
Powiązane pytania
Nowe pytania
linq
Language Integrated Query (LINQ) jest składnikiem Microsoft .NET Framework, który dodaje natywne możliwości wykonywania zapytań danych do języków .NET. W razie potrzeby rozważ użycie bardziej szczegółowych tagów, na przykład [linq-to-sql], [linq-to-entity] / [entity-framework] lub [plinq]