Wygląda na problem z kurczakiem i jajkami.
Możesz zmusić funkcję zapisu do zapisu w jakimś magazynie danych, ale nigdy nie wiesz, że zapisałeś ją poprawnie bez przetestowanej funkcji odczytu.
Możesz zrobić funkcję odczytu z magazynu danych, ale jak umieścić rzeczy w tym magazynie danych, aby można je było czytać bez przetestowanej funkcji zapisu?
EDYTOWAĆ:
Łączę się z bazą danych SQL i dokonuję transakcji w celu zapisywania i ładowania obiektów do użycia. Nie ma sensu testować funkcji dostępu udostępnianych przez DB, ale pakuję takie funkcje DB, aby serializować / deserializować obiekty. Chcę mieć pewność, że poprawnie piszę i czytam odpowiednie dane do iz bazy danych.
To nie jest jak dodawanie / usuwanie, jak wspomina @snowman. Chcę wiedzieć, że treść, którą napisałem, jest poprawna, ale wymaga dobrze przetestowanej funkcji odczytu. Kiedy czytam, chcę mieć pewność, że mój odczyt poprawnie utworzył obiekt równy temu, co zostało napisane; ale to wymaga dobrze przetestowanej funkcji zapisu.
Odpowiedzi:
Zacznij od funkcji odczytu.
W konfiguracji testowej : utwórz bazę danych i dodaj dane testowe. za pośrednictwem skryptów migracji lub z kopii zapasowej. Ponieważ to nie jest twój kod, nie wymaga testu w TDD
W teście : zaimplementuj swoje repozytorium, wskaż na testową bazę danych i wywołaj metodę Read. Sprawdź, czy dane testowe zostały zwrócone.
Teraz masz w pełni przetestowaną funkcję odczytu, możesz przejść do funkcji zapisu, która może użyć istniejącego odczytu do zweryfikowania własnych wyników
źródło
Często po prostu piszę, a potem czytam. np. (pseudokod)
Dodano później
Oprócz tego, że to rozwiązanie jest „prgamatyczne” i „wystarczająco dobre”, można argumentować, że inne rozwiązania testują niewłaściwe działanie . Testowanie, czy łańcuchy lub instrukcje SQL pasują do siebie, nie jest strasznym pomysłem, sam to zrobiłem, ale testuję efekt uboczny i jest delikatny. Co się stanie, jeśli zmienisz wielkie litery, dodasz pole lub zaktualizujesz numer wersji w swoich danych? Co się stanie, jeśli sterownik SQL zmieni kolejność wywołań wydajności lub zaktualizowany serializator XML doda dodatkowe miejsce lub zmieni wersję schematu?
Teraz, jeśli musisz ściśle przestrzegać jakiejś oficjalnej specyfikacji, zgadzam się, że sprawdzenie drobnych szczegółów jest właściwe.
źródło
Nie rób Nie testuj We / Wy urządzenia. To strata czasu.
Logika testu jednostkowego. Jeśli jest dużo logiki, którą chcesz przetestować w kodzie I / O, powinieneś przeformułować swój kod, aby oddzielić logikę tego, jak robisz I / O i co robisz I / O od faktycznej działalności wykonywania I / O (co jest prawie niemożliwe do przetestowania).
Aby nieco rozwinąć, jeśli chcesz przetestować serwer HTTP, powinieneś to zrobić poprzez dwa rodzaje testów: testy integracyjne i testy jednostkowe. Testy jednostkowe w ogóle nie powinny wchodzić w interakcje z I / O. Jest to powolne i wprowadza wiele błędów, które nie mają nic wspólnego z poprawnością kodu. Testy jednostkowe nie powinny zależeć od stanu twojej sieci!
Twój kod powinien się rozdzielić:
Pierwsze dwa obejmują logikę i decyzje i wymagają testów jednostkowych. Ostatni nie wymaga podejmowania wielu, jeśli w ogóle, decyzji i można go cudownie przetestować za pomocą testów integracyjnych.
Właściwie jest to po prostu dobry projekt, ale jednym z powodów jest to, że ułatwia testowanie.
Oto kilka przykładów:
źródło
Nie wiem, czy to standardowa praktyka, czy nie, ale działa mi dobrze.
W moich implementacjach odczytu i zapisu poza bazą danych używam własnych metod
toString()
ifromString()
metod jako szczegółów implementacji.Można je łatwo przetestować w izolacji:
Dla rzeczywistych metod odczytu i zapisu mam jeden test integracji, który fizycznie odczytuje i pisze w jednym teście
Nawiasem mówiąc: czy jest coś złego w jednym teście, w którym test odczytuje / zapisuje razem?
źródło
Znane dane muszą być sformatowane w znany sposób. Najłatwiejszym sposobem na wdrożenie tego jest użycie stałego ciągu i porównanie wyniku, jak opisano w @ k3b.
Nie jesteś jednak ograniczony do stałych. Może istnieć wiele właściwości zapisanych danych, które można wyodrębnić przy użyciu innego rodzaju analizatora składni, takich jak wyrażenia regularne, a nawet sondy ad hoc szukające cech danych.
Jeśli chodzi o odczytywanie lub zapisywanie danych, przydatne może być posiadanie systemu plików w pamięci, który umożliwia uruchamianie testów bez możliwości ingerencji innych części systemu. Jeśli nie masz dostępu do dobrego systemu plików w pamięci, użyj tymczasowego drzewa katalogów.
źródło
Użyj iniekcji zależności i kpiny.
Nie chcesz testować sterownika SQL i nie chcesz sprawdzać, czy baza danych SQL jest w trybie online i czy została poprawnie skonfigurowana. Byłoby to częścią testu integracyjnego lub systemowego. Chcesz przetestować, czy Twój kod wysyła instrukcje SQL, które powinien wysłać, i czy interpretuje odpowiedzi tak, jak powinien.
Więc jeśli masz metodę / klasę, która ma coś zrobić z bazą danych, nie każ jej uzyskać połączenia z bazą danych. Zmień go tak, aby obiekt reprezentujący połączenie z bazą danych był do niego przekazywany.
W kodzie produkcyjnym przekaż rzeczywisty obiekt bazy danych.
W testach jednostkowych przekaż pozorowany obiekt, który zachowuje się tak, jakby rzeczywista baza danych nie kontaktowała się z serwerem bazy danych. Wystarczy, że sprawdzi, czy odbiera instrukcje SQL, które ma otrzymać, a następnie odpowiada na stałe.
W ten sposób możesz przetestować warstwę abstrakcji bazy danych, nawet bez potrzeby posiadania rzeczywistej bazy danych.
źródło
Jeśli używasz obiektu relacyjnego mapowania obiektów, zwykle istnieje powiązana biblioteka, której można użyć do przetestowania poprawności działania mapowań poprzez utworzenie agregacji, utrwalenie jej i ponowne załadowanie z nowej sesji, a następnie weryfikację stanu względem oryginalny obiekt.
NHibernate oferuje testy specyfikacji trwałości . Można go skonfigurować do pracy ze sklepem w pamięci w celu szybkich testów jednostkowych.
Jeśli zastosujesz najprostszą wersję wzorców repozytorium i jednostki pracy i przetestujesz wszystkie swoje odwzorowania, możesz liczyć na to, że wszystko będzie działać dobrze.
źródło