Testowanie kodu z entity frameworkiem w 2024

0

Jak pisać kod, który do zapisu i pobierania danych używa ef core w 2024? Na tutorialach zazwyczaj temat kończy się na IEntityRepository, gdzie nie ma nawet unit of work. Z drugiej strony jest podejście z in-memory db, ale one mają swoje ograniczenia i jeżeli testujemy kod, który wymaga wsparcia dla danej funkcjonalności bazy danych to taki może nas wprowadzić w błąd. Dać złudne pozory bezpieczeństwa.

Proszę o pomoc. Chce być lepszym w pisaniu testów.

3

Jak chcesz mieć pewność że kod będzie działać w praktyce to najlepsze testy są na prawdziwej aplikacji z prawdziwą bazą.
Mockowanie w unit testach sprawia, że kod jest trochę w innym świecie i nie zawsze pomyślne testy oznaczają, że wszystko będzie działać po włączeniu.
Unit testy przydają się tylko do testowania wyekstraktowanej logiki algorytmów niezależnej od otoczenia.

0
AbcDefGhi napisał(a):

Jak chcesz mieć pewność że kod będzie działać w praktyce to najlepsze testy są na prawdziwej aplikacji z prawdziwą bazą.
Mockowanie w unit testach sprawia, że kod jest trochę w innym świecie i nie zawsze pomyślne testy oznaczają, że wszystko będzie działać po włączeniu.
Unit testy przydają się tylko do testowania wyekstraktowanej logiki algorytmów niezależnej od otoczenia.

Ja jestem typowym crudziarzem. Jedynie mapowanie filtrów i przekształcanie ich do expression tree, które trafiają do ORMa.
Nie chcę się tylko ograniczać testami E2E. Bo ich wykonanie długo trwa.

2

Testcontainers: https://dotnet.testcontainers.org/? Uruchamia ci faktyczną instancję bazy do testów, a nie polega na bazach InMemory.

1

A co chcesz w ogóle testować? Do testowania logiki biznesowej lub aplikacyjnej wystarczy fake lub stub repozytorium czy czegoś podobnego bo interesuje nas logika, a nie szczegóły implementacyjne warstwy infrastruktury. Jeżeli chcesz testy, żeby upewnić się, że przy zapisie danych nic się nie posypie - optimistic locking, constrainty, wywoływanie funkcji/procedur składowanych w sql to tylko testcontainers i prawdziwa baza.

2
Anatolijus napisał(a):

Jak pisać kod, który do zapisu i pobierania danych używa ef core w 2024? Na tutorialach zazwyczaj temat kończy się na IEntityRepository, gdzie nie ma nawet unit of work.

Przecież DbContext to jest unit of work. Wystarczy nie robić jakichś durnych IEntityRepository.

Ktos napisał(a):

Testcontainers: https://dotnet.testcontainers.org/? Uruchamia ci faktyczną instancję bazy do testów, a nie polega na bazach InMemory.

Albo po prostu obraz dockera z daną bazą.

0

A może jakiś własny interfejs/klasa abstrakcyjnaIDataAccess per bounded context, który ma metodę Commit oraz odpowiednie metody do CRUD z specification pattern w parametrze. Trochę więcej kodu na start, ale pełna swoboda w mockowaniu oraz równoległego wykonywania testów.

1

No, ale jak chcesz mockować, to testy CRUDa nie będą rzetelne.

0

Tak jak każdego innego kodu który ma związek z persystencją. Nałóż abstrakcję i odpal ją w testach.

1

@somekind:

somekind napisał(a):
Anatolijus napisał(a):

Przecież DbContext to jest unit of work. Wystarczy nie robić jakichś durnych IEntityRepository.

Ten trend chyba przywędrował z YT gdzie twórcy starają się na siłę pokazać że ich podejście jest lepsze bo inne. Robienie abstrakcji ponad abstrakcją jaką już samą w sobie jest EF moim zdaniem jest dużym błędem. Jedyną sytuacją w której takie coś mogłoby mieć miejsce to gdy mamy podpiętą bazę przez EF, potem kolejna np. redis/mongo i jeszcze jakieś inne źródło danych i chcemy to mieć opakowane jakoś w jedno repo. Tymczasem tworzą UoW sami, wszystkie metody zapisu/odczytu/transakcji sami, a na sam koniec nie piszą testów i nie wiadomo czy błąd jest tu czy tam.

Po to wstrzykuje się interfejs IDbContext żeby go mockować, mockujesz go, wrzucasz tam fejk dane i wtedy logika biznesowa wykonuje sie na fejk danych. Czy to jest zbyt proste że trzeba to skomplikować kolejnymi głupimi abstrakcjami?

1
bagietMajster napisał(a):

Ten trend chyba przywędrował z YT gdzie twórcy starają się na siłę pokazać że ich podejście jest lepsze bo inne.

Ja jestem tak stary, że pamiętam programowanie bez YT, tutoriale były pisane na blogach i portalach branżownych, i było dokładnie tak samo jeśli chodzi o promowanie złych praktyk.

Tymczasem tworzą UoW sami, wszystkie metody zapisu/odczytu/transakcji sami, a na sam koniec nie piszą testów i nie wiadomo czy błąd jest tu czy tam.

Całkiem możliwe, że nie piszą celowo, bo testy by pokazały, że ten UoW wcale nie pozwala na zapis do dwóch repozytoriów w jednej transakcji.

1
bagietMajster napisał(a):

Po to wstrzykuje się interfejs IDbContext żeby go mockować, mockujesz go, wrzucasz tam fejk dane i wtedy logika biznesowa wykonuje sie na fejk danych. Czy to jest zbyt proste że trzeba to skomplikować kolejnymi głupimi abstrakcjami?

Może czegoś nie dostrzegam, ale taki interfejs musimy stworzyć samemu, dodać go do klasy, która dziedziczy po DbContext i mockować DbSety.

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