Repozytorium tłumaczy z Twojej domeny na środowisko DAL, takie jak NHibernate lub Doctrine, lub klasy wykonujące SQL. Oznacza to, że twoje repozytorium będzie wywoływać metody na tym frameworku w celu wykonania swoich obowiązków: twoje repozytorium konstruuje zapytania potrzebne do pobrania danych. Jeśli nie używasz frameworka ORM (mam nadzieję, że tak ...), repozytorium byłoby miejscem, w którym budowane są surowe instrukcje SQL.
Najbardziej podstawową z tych metod jest save: w większości przypadków po prostu przekaże obiekt z repozytorium do jednostki pracy (lub sesji).
public void Save(Car car)
{
session.Save(car);
}
Ale spójrzmy na inny przykład, na przykład pobranie samochodu po jego identyfikatorze. Może to wyglądać
public function GetCarWithId(String id)
{
return Session.QueryOver<Car>()
.Where(x => x.Id == id)
.SingleOrDefault();
}
Wciąż nie jest to zbyt skomplikowane, ale możesz sobie wyobrazić w wielu warunkach (zdobądź wszystkie samochody wyprodukowane po 2010 roku dla wszystkich marek w grupie „Volkswagen”), to staje się trudne. Więc w prawdziwym stylu TDD musisz to przetestować. Można to zrobić na kilka sposobów.
Opcja 1: wyśmiewać wywołania wykonane w ramach ORM
Jasne, możesz kpić z obiektu sesji i po prostu stwierdzić, że wykonano właściwe wywołania. Chociaż testuje repozytorium, to naprawdę nie jest test- napędzany bo jesteś po prostu testuje że repozytorium wewnętrznie wygląda tak, jak chcesz go. Test zasadniczo mówi „kod powinien wyglądać tak”. Mimo to jest to prawidłowe podejście, ale wydaje się, że ten rodzaj testu ma bardzo małą wartość.
Opcja 2: (Re) zbuduj bazę danych z testów
Niektóre frameworki DAL umożliwiają budowanie kompletnej struktury bazy danych na podstawie plików mapowania tworzonych w celu mapowania domeny na tabele. W przypadku tych frameworków sposobem testowania repozytoriów jest często tworzenie bazy danych z bazą danych w pamięci w pierwszym kroku testu i dodawanie obiektów za pomocą struktury DAL do bazy danych w pamięci. Następnie możesz użyć repozytorium w bazie danych w pamięci, aby sprawdzić, czy metody działają. Testy te są wolniejsze, ale bardzo ważne i przeprowadzają testy. Wymaga to pewnej współpracy ze strony środowiska DAL.
Opcja 3: Test na rzeczywistej bazie danych
Innym podejściem jest testowanie rzeczywistej bazy danych i izolowanie najbardziej nieprzystosowanych. Możesz to zrobić na kilka sposobów: otoczyć testy transakcją, wyczyścić ręcznie (nie byłoby to tak trudne do utrzymania), całkowicie odbudować bazę danych po każdym kroku ... W zależności od budowanej aplikacji może to lub może nie być wykonalnym. W moich aplikacjach mogę całkowicie zbudować lokalną bazę danych programowania z kontroli źródła, a moje unittests na repozytoriach używają transakcji, aby w pełni odizolować testy od siebie (otwarta transakcja, wstawianie danych, repozytorium testów, transakcja wycofywania). Każda kompilacja najpierw konfiguruje lokalną bazę danych programowania, a następnie wykonuje transakcje izolowane od transakcji dla repozytoriów w tej lokalnej bazie danych programowania. To'
Nie testuj DAL
Jeśli używasz frameworka DAL, takiego jak NHibernate, unikaj konieczności testowania tego frameworka. Możesz przetestować pliki mapowania, zapisując, pobierając, a następnie porównując obiekt domeny, aby upewnić się, że wszystko jest w porządku (pamiętaj o wyłączeniu buforowania), ale nie jest tak wymagane, jak wiele innych testów, które powinieneś pisać. Zazwyczaj robię to głównie w przypadku zbiorów rodziców z warunkami dotyczącymi dzieci.
Podczas testowania zwrotu repozytoriów wystarczy sprawdzić, czy jakaś właściwość identyfikująca obiekt w domenie jest zgodna. Może to być identyfikator, ale w testach często bardziej korzystne jest sprawdzenie właściwości czytelnej dla człowieka. W części „zdobądź wszystkie samochody wyprodukowane po 2010 roku…” można po prostu sprawdzić, czy pięć samochodów zostało zwróconych, a tablice rejestracyjne to „wstaw listę tutaj”. Dodatkową korzyścią jest to, że zmusza cię do myślenia o sortowaniu ORAZ twój test automatycznie wymusza sortowanie. Byłbyś zaskoczony, jak wiele aplikacji albo sortuje wiele razy (wróć sortowane z bazy danych, sortuj przed utworzeniem obiektu widoku, a następnie sortuj obiekt widoku, wszystkie na tę samą właściwość na wszelki wypadek ) lub domyślnie zakładaj sortowanie repozytorium i przypadkowo usuń które były po drodze, łamiąc interfejs użytkownika.
„Test jednostkowy” to tylko nazwa
Moim zdaniem testy jednostkowe przeważnie nie powinny trafić do bazy danych. Budujesz aplikację tak, aby każdy fragment kodu, który potrzebuje danych ze źródła, robił to z repozytorium, a repozytorium jest wstrzykiwane jako zależność. Pozwala to na łatwe kpiny i wszystkie dobrodziejstwa TDD, jakie chcesz. Ale w końcu chcesz się upewnić, że twoje repozytoria wykonują swoje obowiązki, a jeśli najłatwiejszym sposobem jest trafienie do bazy danych, to niech tak będzie. Długo porzuciłem pogląd, że „testy jednostkowe nie powinny dotykać bazy danych” i dowiedziałem się, że istnieją bardzo realne powody, aby to zrobić. Ale tylko jeśli możesz to zrobić automatycznie i wielokrotnie. A pogoda nazywamy takim testem „testem jednostkowym” lub „testem integracyjnym” jest dyskusyjna.