jak testowac fasady?

0

mam pobrac dane z prawdziwej bazy? wrzucac fejkowe dane do derby? (ale duzo trzeba byloby ich wrzucac) uzyc czegos w stylu arquillian?

0

Co masz na myśli fasady? Ja bym podniosł testcontainer z bazą danych.

1

Czy Twoja fasada to tak na prawde repository?

0

niekoniecznie niebezpieczne, po tobaza developerska i tak, ale co jezeli ktos sobie nazwal lokalnie baze inaczej , to mu test nie przejdzie jak napisze z test z laczeniem sie po jdbc url —

No i od tego jest albo TestContainer albo H2/inna in memory. A że danych dużo? No trudno, albo chcesz testować aplikacje, albo chcesz testować Mockito.

0

czytalam ostatnio o derby/arquillian/testcontainers. Niestety zadne z tych rozwazan (albo nie znam je zbyt dobrze) nie rozwiazuje problemu sprawnego dostarczenia potrzebnych danych do testowej bazy. Moge sprawdzic na jakich tabelach sa operacje w fasadach i tylko te tabele wyciaganc z prawdziej bazy i insertowac je do testowej. Zrobilam np metode przyjmujaca nazwe tabeli wyciagajacej z niej wszystkie elementy resultsetem, a potem to jest mapowane to listy elementow JPA i wrzucone do bazy testowej Ale wtedy ja moge miec na tescie 200 elementow, a ktos moze miec 300. Jakiego asserta wtedy uzyc? Nie zrobie asserta typu "to filtrowanie wyciagnie 40 elementow", bo komus moze wyciagnac 50. Jedyny sensowny to sprawdzenie np czy wszystkie elementy wyciagniete maja jakas wspolna ceche np ta sama wartosc pewnego fielda po ktorym byl select. Inne rozwiazanie: dodawaj potrzebne elementy recznie, np jak metoda dziala na tabelach t1,t2,t3 to w metodzie testowej wrzuc do bazy po jednym elementu fejkowym o danych typach i odpowiednich fieldach. Problemem jest to ze dany obiekt JPA moze miec nawet kilkanasie fieldow notnullable wiec konstrukcje takich obiektow sa uciazliwe. Jeszcze problem z samymi bazami inmemory - np derby nie implementuje limit. Wiec test dowolnej metody wykorzystujacej limit sie wykrzaczy z automatu. Jest coprawda cos takiego jak pg-embedded ale to jakas amatorska biblioteka i nie dziala u mnie z wsadem podanym z liquibase

1
lambdadziara napisał(a):

czytalam ostatnio o derby/arquillian/testcontainers.

  • derby to zabawka
  • arquillian nie znam
  • testcontainers działa z PosgreSQLem bez problemu

Zrobilam np metode przyjmujaca nazwe tabeli wyciagajacej z niej wszystkie elementy resultsetem, a potem to jest mapowane to listy elementow JPA i wrzucone do bazy testowej

  • W każdym teście łączysz się do bazy produkcyjnej? o_0"
  • Wyciągasz dane resultsetem żeby przemapowywać na encje i zapisywać za pomocą JPA? A to nie możesz od razu wyciągać encji za pomocą JPA?

Jest coprawda cos takiego jak pg-embedded ale to jakas amatorska biblioteka i nie dziala u mnie z wsadem podanym z liquibase

Jak pisałem prawdziwy PostgreSQL z testcontainers działa, nie ma potrzeby używać pg-embedded

0
KamilAdam napisał(a):
lambdadziara napisał(a):

czytalam ostatnio o derby/arquillian/testcontainers.

  • derby to zabawka
  • arquillian nie znam
  • testcontainers działa z PosgreSQLem bez problemu
  • W każdym teście łączysz się do bazy produkcyjnej? o_0"
  • Wyciągasz dane resultsetem żeby przemapowywać na encje i zapisywać za pomocą JPA? A to nie możesz od razu wyciągać encji za pomocą JPA?

Jest coprawda cos takiego jak pg-embedded ale to jakas amatorska biblioteka i nie dziala u mnie z wsadem podanym z liquibase

Jak pisałem prawdziwy PostgreSQL z testcontainers działa, nie ma potrzeby używać pg-embedded

tzn na poczatku testu w @BeforeAll a nie w kazdym testcase, ale masz racje jak mam paczke a wniej kilkanascie plikow testowych to kazdy bedzie mial metode @BeforeAll i kazdy osobno polaczy sie i zrobi wsad. Nie wiem jak to inaczej rozwiazac, bo testy moga sie wykonywac w roznej kolejnosci. Nie wiem jak wyciagac dane z uzyciem hibernate. EntityManager korzysta z persistence.xml i persistenceunit prawda? Mam wykorzystac persistenceunit wykorzystywany juz w serwerze aplikacyjnym? czy zrobic nowe persistence.xml w resources. Bo jeden persistence.xml juz jest - dla derby. Testcontainers uzywa dockera prawda? Wiec kazdy musi miec zainstalowanego dockera oddzielnie i ajkos go skonfigurowac zeby testy przeszly? Co jak ktos korzysta z windowsa?

2

Nie bardzo rozumiem problem. Tak, trzeba napisać sporo kodu żeby przygotować stan aplikacji pod testy no ale to jest po prostu część testów i nie uciekniesz przed tym. Kopiowanie danych z jakiegoś testa to moim zdaniem słabe rozwiązanie, bo nie kontrolujesz co tam jest i cięzko ogarnać tak wszystkie/trudne test-cases.

Ja osobiśćie preferuje napisanie sobie ładnego DSLa do opisu stanu aplikacji i napisanie kodu który na jego podstawie załaduje ci odpowiedni stan w bazie. Tzn w kodzie testu mam np.

TestConfiguration configuration = testHelper.newConfiguration()
    .withX()
    .withY()
    .withZ(V.builder().with.....build())
...
    .setup();

I teraz to setup na końcu wywołuje kaskadę różnych magicznych rzeczy w stylu:

  • inserty do bazy danych
  • konfigurowanie embedded http serwerów które imitują inne serwisy

I voila, teraz mozesz wykonać faktyczny test, wiedząc że masz skonfigurowany odpowiedni stan aplikacji. A potem w jakimś After jest delete from na wszystkich tabelach po każdym teście.

Oczywiście to wymaga spędzenia trochę czasu nad tym DSLem, ale generalnie się opłaca :)

Plus jest też taki, że nie limitują cię bzdury w stylu na teście nie mamy danych gdzie user ma 3 nogi, bo robisz sobie withUser(User.builder().withLegs(3).build()) i cyk.

1
  1. Upewnij się, że masz zdefiniowane obiekty biznesowe.
  2. Upewnij się, że masz interfejsy typu Provider dla takich obiektów, które ogarniają zapisywanie i odczytywanie (API, DB etc.)
  3. Przygotuj sobie neutralne prototypy takich obiektów. Osobiście zwykle tworzę sobie to w dedykowane klasie. UserPrototypes.ROMAN, UserPrototypes.DAVID, CityPrototypes.WARSAW etc.
  4. Przygotuj sobie utile typu. givenUser(ROMAN); givenCity(WARSAW)

Mając to piszę zwykle podstawowy test. A następnie kolejne gdzie troszkę modyfikuje prototypy jakimś builderem lub .copy()

Inwestycja w zdefiniowanie prototypów i providerów oszczędza czas potrzebny na definiowanie bazyliona kombinacji moków. Oszczędza też nerwów gdy musisz dodać jakieś nowe wymaganie do pola, które nie było wykorzystywane i okazuje się, że we wszystkie testy failują bo mamy tam nulle.

4

@lambdadziara:

Mozesz pokazac to dsl

Mówisz, masz: https://github.com/Pharisaeus/almost-s3/blob/master/test/src/test/java/net/forprogrammers/almosts3/test/DownloadTest.java
Cały toy-project żeby pokazać o co chodzi. Quality dość biedne i design też taki sobie (ja bym np. w ogóle nie miał tej bazy danych ale pytanie było m.in. o bazę), ale naklepałem to przed chwilą na kolanie żeby łatwiej było wyjaśnić ideę.
Jednocześnie chciałem żeby to miało jakiś minimalny sens i jakąś znikomą logikę, jest tam baza danych (ale nie ma cruda :P), są inne mikroserwisy z których ten serwis korzysta i jest też opcjonalny token auth.

1

Szanowna sieci kont... wróć... drodzy forumowicze ;)

Mam aplikację składającą się z dwóch modułów (podział by package, beż żadnych modułów mavenowych itp póki co).
Każdy moduł udostępnia na zewnątrz jedynie jakąś fasadę i dto.
Z prezentacji Kuby Nabrdalika ( ) dowiedziałem się, że wystarczy, że napiszę unit testy testujące fasadę więc próbuję tak zrobić.

Pokrótce przedstawię sytuację:

  1. Moduł A posiada zależność do pakietowej klasy N która w swoim wnętrzu korzysta z fasady modułu B
  2. Fasada modułu B (wykorzystywana w klasie N) z kolei posiada własne zależności do np. dwóch rodzajów repozytorium i jakiejś klasy typu factory (w module B naturalnie wszystko pakietowe z wyjątkiem wspomnianej fasady i jakiegoś tam dto).

Jak widać moduł A gdzieś w swoim wnętrzu posiada zależność do modułu B.
Zastanawiam się teraz, czy aby te testy miały sens mam w palca gdzieś tworzyć wszystkie te klasy wraz z ich zależnościami (repozytoria zasadniczo prosto stworzyć jakieś typu inMemory na bazie mapy) czy mockować wszystko z modułu B (podczas testów modułu A) i na odwrót?

2

Jeżeli ten moduł B jest poprawnie zrobiony, tak jak u Nabrdalika, to stworzenie jego instancji testowej z np. InMemoryRepo to jest jedna linijka kodu - polecam więc to podejście.

0

Zastanawiam się, czy nie jest błędem, że wspomniana klasa N (z modułu A) bezpośrednio komunikuje się z fasadą modułu B.
Czy aby przypadkiem klasa N nie powinna się komunikować jedynie z fasadą ze swojego pakietu (moduł A) i dopiero fasada modułu A uderza do fasady modułu B :)

0

Jak to sobie wyobrażasz? Fasada A ma pewnie zależność do klasy N, a żeby zrobić to co mówisz to N musi mieć zależność do fasady A, czyli masz circular dependency

0

W takim razie jak powinienem testować moduł A? Mockując cały moduł B w teście fasady A i odwrotnie, analogicznie dla fasady B?

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