Gdzieś w twojej bazie kodu jest wiersz kodu, który wykonuje rzeczywistą akcję połączenia ze zdalną bazą danych. Ten wiersz kodu jest 9 razy na 10 wywołaniem „wbudowanej” metody dostarczanej przez biblioteki środowiska wykonawczego specyficzne dla Twojego języka i środowiska. Jako taki nie jest to „twój” kod, więc nie musisz go testować; na potrzeby testu jednostkowego możesz mieć pewność, że to wywołanie metody będzie działać poprawnie. To, co możesz i powinieneś nadal testować w swoim pakiecie testów jednostkowych, to takie, jak upewnienie się, że parametry, które będą używane dla tego wywołania, są zgodne z oczekiwaniami, takie jak upewnienie się, że parametry połączenia są poprawne, instrukcja SQL lub nazwa procedury składowanej.
Jest to jeden z celów stojących za ograniczeniem, że testy jednostkowe nie powinny pozostawiać ich środowiska uruchomieniowego „piaskownicy” i być zależne od stanu zewnętrznego. To właściwie całkiem praktyczne; celem testu jednostkowego jest sprawdzenie, czy kod, który napisałeś (lub masz zamiar napisać, w TDD) zachowuje się tak, jak się spodziewałeś. Kod, którego nie napisałeś, taki jak biblioteka, której używasz do wykonywania operacji na bazie danych, nie powinien wchodzić w zakres żadnego testu jednostkowego, z bardzo prostego powodu, że go nie napisałeś.
W pakiecie testów integracji ograniczenia te są złagodzone. Teraz już mogęprojektuj testy, które dotykają bazy danych, aby upewnić się, że napisany kod działa dobrze z kodem, którego nie zrobiłeś. Te dwa pakiety testowe powinny jednak pozostać posegregowane, ponieważ pakiet testów jednostkowych jest bardziej skuteczny, im szybciej działa (dzięki czemu można szybko sprawdzić, czy wszystkie twierdzenia deweloperów dotyczące ich kodu są nadal aktualne), a prawie z definicji test integracji jest wolniejszy o rząd wielkości ze względu na dodatkowe zależności od zasobów zewnętrznych. Pozwól build-botowi obsługiwać uruchamianie pełnego pakietu integracyjnego co kilka godzin, wykonując testy blokujące zasoby zewnętrzne, aby programiści nie stawali sobie na nogi, uruchamiając te same testy lokalnie. A jeśli kompilacja się zepsuje, co z tego? Dużo większą wagę przywiązuje się do zapewnienia, że build-bot nigdy nie zawiedzie kompilacji, niż prawdopodobnie powinno być.
To, jak ściśle możesz się do tego zastosować, zależy od dokładnej strategii łączenia się z bazą danych i wysyłania do niej zapytań. W wielu przypadkach, w których musisz używać szkieletowej struktury dostępu do danych, na przykład obiektów SqlConnection i SqlStatement ADO.NET, cała opracowana przez Ciebie metoda może składać się z wbudowanych wywołań metod i innego kodu zależnego od posiadania połączenie z bazą danych, dlatego najlepszym rozwiązaniem w tej sytuacji jest wyśmiewanie się z całej funkcji i zaufanie do pakietów testowych integracji. Zależy to również od tego, jak chętnie zaprojektujesz swoje klasy, aby umożliwić zastąpienie określonych wierszy kodu do celów testowych (takich jak sugestia Tobiego dotycząca wzorca metody szablonów, co jest dobre, ponieważ pozwala na „częściowe kpiny”
Jeśli model trwałości danych opiera się na kodzie w warstwie danych (takim jak wyzwalacze, przechowywane procy itp.), To po prostu nie ma innego sposobu na wykonanie kodu, który sam piszesz, niż opracowanie testów, które albo żyją wewnątrz warstwy danych, albo przekraczają granica między środowiskiem uruchomieniowym aplikacji a systemem DBMS. Z tego powodu purysta powiedziałby, że tego wzoru należy unikać na rzecz czegoś w rodzaju ORM. Nie sądzę, żebym posunął się tak daleko; nawet w dobie zapytań zintegrowanych z językiem i innych sprawdzanych przez kompilator operacji trwałości zależnych od domeny widzę wartość w blokowaniu bazy danych tylko do operacji ujawnionych za pomocą procedury składowanej, i oczywiście takie procedury przechowywane muszą być zweryfikowane za pomocą zautomatyzowanego testy. Ale takie testy nie są testami jednostkowymi . Są integracją testy.
Jeśli masz problem z tym rozróżnieniem, zwykle opiera się ono na dużym znaczeniu przywiązywanym do pełnego „pokrycia kodu”, czyli „pokrycia testu jednostkowego”. Chcesz się upewnić, że każdy wiersz kodu jest objęty testem jednostkowym. Szlachetny cel na pierwszy rzut oka, ale mówię, że to miazga; ta mentalność nadaje się do anty-wzorów wykraczających daleko poza ten konkretny przypadek, takich jak pisanie testów bez asercji, które wykonują, ale nie ćwicząTwój kod. Tego rodzaju przebiegi końcowe wyłącznie ze względu na numery ubezpieczenia są bardziej szkodliwe niż złagodzenie minimalnego zakresu ubezpieczenia. Jeśli chcesz mieć pewność, że każda linia bazy kodu jest wykonywana przez jakiś automatyczny test, to jest łatwe; podczas obliczania wskaźników zasięgu kodu należy uwzględnić testy integracyjne. Możesz nawet pójść o krok dalej i odizolować te sporne testy „Itino” („Integracja tylko w nazwie”), a między pakietem testów jednostkowych a tą podkategorią testów integracyjnych (które powinny nadal działać dość szybko) powinieneś dostać cholerę prawie blisko pełnego zasięgu.