2012-11-14 11 views
7

Piszę prostą aplikację, która odczyta niektóre rekordy i wstawi je do bazy danych. Napisałem procedurę przechowywaną, która obsługuje logikę wstawiania i planuję ją przetestować osobno. Teraz chciałbym napisać dobry test jednostkowy dla części logiki, która pobiera obiekt biznesowy i przekazuje go do wywołania procedury przechowywanej.W jaki sposób powinienem przetestować Java, która wywołuje procedurę przechowywaną MySQL?

myślę co chcę zrobić, to przekazać próbną połączenia z bazą danych, a następnie stwierdzić, że połączenie jest wykonane z oczekiwanymi wartościami parametrów:

Connection dbConnection = makeMockConnection(); // how? 
MyObjectWriter writer = new MyObjectWriter(dbConnection); 
writer.write(someSampleObject); 
// somehow assert that dbConnection called 
// `sp_saveMyObject` with param values x, y, and z 

Jednak wydaje się, że dużo pracy kopać wewnątrz java.sql.Connection, zrozumieć, jak to działa, a następnie kpić z wszystkich wyników. Czy istnieje biblioteka testowa, która robi to wszystko dla mnie? Czy podejdę do tego w niewłaściwy sposób?

+0

Prześmiewanie połączenia w celu sprawdzenia, czy wywoływana jest metoda, jest naprawdę łatwe. Powinieneś zapoznać się z [Mockito] (http://code.google.com/p/mockito/) – Kai

+0

Próbuję uniknąć ograniczenia logiki biznesowej do uruchomienia w określony sposób - mogę nazwać "Connection.createStatement" lub 'Connection.prepareStatement' lub' Connection.prepareCall' lub nawet 'Connection.nativeSql', z których każdy jest * poprawny * (w tym przypadku dane zostają przekazane do procedury). Próbuję uniknąć wyszydzania * wszystkich * tych rzeczy, albo przynajmniej samemu pisać te drwiny. – Coderer

Odpowiedz

2

Można utworzyć bazę danych HSSQL w pamięci przy pomocy fałszywej procedury składowanej. Sprytny sproc wstawiłby wiersz do tabeli, aby pokazać, że został uruchomiony i jakie były jego parametry. Uruchom kod w trakcie testu, a następnie spójrz do bazy danych, aby zobaczyć, co się stało.

+0

Ile to kosztuje w testach? W tej chwili pozostałe testy mogą być uruchamiane w ciągu kilku milisekund - czy czas standup/rozpadu jest znaczący? – Coderer

+1

Nigdy go nie wyliczyłem, ale zgaduję, że kilka 10 ms wynika z plików tymczasowych, które tworzy. Gdybyś miał tylko garść takich testów, nie martwiłbyś się. Gdybyś miał tysiące, możesz. Zawsze można udostępniać tę samą instancję db w wielu testach, o ile wyczyścisz tabelę między nimi. Używam w pamięci dbs do testowania strasznie dużo i stwierdzam, że wygrana w prostocie znacznie przewyższa czas wykonania. Nie musisz zmieniać żadnego kodu, tylko przepuść inny ciąg połączenia jdbc. to ogromna zaleta. – AutomatedMike

+0

Mam problem ze znalezieniem prostego przewodnika, aby zacząć z tym - dokumentacja HSQLDB to setki stron, a większość postów na blogu itp., Które mogę znaleźć na temat testowania jednostkowego za pomocą HSQLDB, są specyficzne dla Hibernacja/wiosna. Po prostu muszę uruchomić bazę danych, dodać tabelę i procedurę przechowywaną, a następnie oderwać ją, gdy skończę. To powinno być łatwe, prawda? – Coderer

0

Możesz użyć wzoru projektu dekoratora do szyderstwa połączenia. Tworzysz prawdziwe połączenie z bazą danych za pomocą używanego sterownika, który jest zawijany przez twoją klasę ConnectionImpl, która implementuje interfejs połączenia i przechowuje rzeczywiste połączenie jako członek.
Każde prawdziwe połączenie, którego naprawdę nie chcesz wykonywać, zastąp go fałszywym kodem, a każde wywołanie pobytu wywołuje identyczną metodę rzeczywistego obiektu połączenia (Deleguj połączenie).
W ten sposób kodujesz jak zwykle, różnią się tylko zwróconym obiektem od metody, która tworzy połączenie.
Teraz, w symulowanym obiekcie (Twój ConnectionImpl) możesz na przykład dodać kod testujący jednostki, który sprawdza dane wejściowe.

+0

Problem polega na tym, że, jak mówię w moim komentarzu do PO, staram się nie wniknąć w wnętrzności połączenia. Opakowanie musiałoby wiedzieć * co * do sprawdzenia, jaki punkt w wykonaniu jest wspólny pomiędzy 4 lub 5 różnymi sposobami osiągnięcia tego samego. Sposób, dużo więcej pracy niż odpowiedź @ AutomatedMike. – Coderer

0

Jeśli nie przejmujesz się tym, jak działa MyObjectWriter, to po prostu byłbym skłonny napisać test integracji i zapomnieć o teście jednostkowym.

Nie wspominacie o tym, jak testujecie procedurę przechowywaną, więc wybaczcie mi, ale ja bym napisał testy około MyObjectWriter, które wywołują rzeczywistą procedurę przechowywaną w bazie danych, a następnie sprawdzają stan bazy danych. Jeśli to możliwe, używałbym bazy danych w pamięci, aby obniżyć czas trwania testu.

Powiązane problemy