Mockowanie warstwy danych i lazy loading

0

Cześć. Mam takie wyzwanie.
Sprzątamy bałagan w monolicie,. Padł pomysł od zewnętrznego architekta, aby zacząć od separacji danych, w taki sposób, aby było generyczne repozytorium dla każdej tabeli (niestety architek umie tylko w C#). Zawierające metody getAll, save, delete. Teraz w wyższej warstwie powinienem poskładać zapytanie, tak aby getAll nie brało całej tabeli, a tylko to co chcę. W .Net jest coś takiego jak Iquerable, wygląda jak stream, tylko że działa w ten sposób, że najpierw jest "filtrowanie", a na końcu dopiero pobiera z repozytorium tylko te dane, których potrzebuje.

Celem jest to, żeby można było w ramach testów jednostkowych podmieniać same repozytoria na mocki.
Wcześniej zespół używał SpringData, więc mam powstrzymywane JpaReposytory w kontroler.

Osobiście wolałbym użyć kompozycji, opakować to repozytorium w jakieś proxy i mockować to proxy na poziomie testów.

Ale może ktoś ma doswiadzczenie z czymś takim i mógłby coś poradzić innego?
Pozdrawiam

0

zacznijcie może od zmiany architekta (naprawdę zna tylko c#, czy chodzi o to że nie zna Javy?)

0

To niestety jest po za moimi kompetencjami

1

Zamiast mockować (stubbować) spróbuj dostarczyć swoją implementację in-memory do testów. Aby to osiągnąć klient repozytorium powinien opierać się na interfejsie (dependency inversion principle). Co do metody „getAll” to moim zdaniem do wyrzucenia. Wystaw tylko te operacje, które są sensowne domenowo. Możesz pisać własne querasy albo pójść krok dalej i np. skorzystać ze specyfikacji https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/

0

@Black007: tak jak pisze @Charles_Ray możesz spróbować rozdzielić warstwy wydzielając interfejs dostępu do danych i wrzucić in-memory implementację do klas pracujących bezpośrednio na surowiźnie (masz key-value, czy relacyjną bazę?). To tak pomijając fakt, że unit test pokrywający CRUD robi chyba jednak trochę za dużo. Zgaduję, że nie ma tych testów za dużo, więc pewnie można byłoby na początek skupić się na wydzieleniu i wrzuceniu interfejsów z danymi w reprezentacji modelu (z obiektami już w reprezentacji na jakiej pracuje system). Robiąc to poczyścisz trochę model (bo pewnie jest w nim sporo elementów bezpośrednio odzwierciedlających reprezentację w bazie danych). Wrzucając te interfejsy do klas testujących funkcjonalność w której coś ma się zmienić / został znaleziony defekt, którego jeszcze nie ogarniam, etc zwykle pozwala mi zidentyfikować źródło smrodku (jakiś dodatkowy ad-hoc select, jakiś update-niespodziankę, etc).

Zasugerowałym CQRS ale to dość złożona koncepcja i może nie być potrzebna w tym projekcie. Zawsze warto poczytać, ponieważ w tym przypadku wygląda, że warto ogarnąć Query-pattern. Tak jak sądzę, że nie ma co testować Create, Update, czy Delete (na poziomie dostępu do danych) to akurat warstwa Read (query właśnie), często sprawia kłopoty i warto tu trochę wysiłku włożyć.

0

Dodam jeszcze od siebie, że warto poszukać miejsc gdzie lepszym rozwiązaniem będzie test integracyjny zamiast unitowego na mockach. W „totalnym” CRUD nie ma czego testować jednostkowo, jednak na pewno jakaś logikę tam masz. Co do propozycji użycia CQRS, nie widzę związku z tematem :)

0
  1. Architekt sugeruje zmianę na CrudRepository, które w zasadzie masz (w Spring Data, JpaRepository jest specjalizacją CrudRepository).
  2. Gdzie masz logikę biznesową? Czy encja JPA są Twoimi obiektami biznesowymi, czy mapujesz encję JPA na encję biznesową?
  3. Co testujesz jednostkowo?
2

Celem jest to, żeby można było w ramach testów jednostkowych podmieniać same repozytoria na mocki.

I kolejny zespół będzie dzielnie testować mocki! :D :D A może jednak nie kombinować tylko do testów wystartować jakieś H2 albo HSQL zamiast zmieniać kod pod testy? A architekt który proponuje aby było generyczne repozytorium dla każdej tabeli aka CRUD to chyba był w hibernacji ostatnie 20 lat.

0

@Shalom: Własnie o tym chciałem napisać, że przecież mogę H2 użyć i testować.

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