Jednym z przykładów niepowodzenia, który chciałbyś przechwycić, jest to, że testowany obiekt wykorzystuje warstwę buforującą, ale nie zachowuje danych zgodnie z wymaganiami. Następnie, jeśli zapytasz obiekt, powie: „tak, mam nową nazwę i adres”, ale chcesz, aby test się nie powiódł, ponieważ tak naprawdę nie zrobił tego, co powinien.
Alternatywnie (i pomijając naruszenie zasady pojedynczej odpowiedzialności) załóżmy, że wymagane jest zachowanie wersji łańcucha zakodowanej w UTF-8 w polu zorientowanym na bajty, ale tak naprawdę trwa Shift JIS. Niektóre inne komponenty będą czytać bazę danych i spodziewa się zobaczyć UTF-8, stąd wymóg. Następnie podróż w obie strony przez ten obiekt zgłosi poprawną nazwę i adres, ponieważ przekonwertuje go z powrotem z Shift JIS, ale błąd nie zostanie wykryty przez twój test. Miejmy nadzieję, że zostanie wykryty w późniejszym teście integracji, ale głównym celem testów jednostkowych jest wczesne wychwycenie problemów i dokładna znajomość odpowiedzialnego komponentu.
Jeśli jeden z nich nie robi tego, co powinien, wtedy jego własny test nie powiedzie się, a my możemy go naprawić i ponownie uruchomić baterię testową.
Nie możesz tego założyć, ponieważ jeśli nie będziesz ostrożny, napiszesz zestaw testów zależnych od siebie. „Czy to oszczędza?” test wywołuje testowaną metodę zapisu, a następnie metodę ładowania, aby potwierdzić zapisanie. „Czy ładuje się?” test wywołuje metodę save, aby skonfigurować urządzenie testowe, a następnie testuje metodę ładowania, aby sprawdzić wynik. Oba testy opierają się na poprawności metody, której nie testują, co oznacza, że żaden z nich nie sprawdza poprawności metody, którą testuje.
Problem polega na tym, że dwa testy, które rzekomo testują różne jednostki, faktycznie robią to samo . Oboje wywołują settera, a następnie gettera, a następnie sprawdzają, czy wynikiem jest oryginalna wartość. Ale chciałeś sprawdzić, czy ustawiający utrzymuje dane, a nie, czy para ustawiający / pobierający działa razem. Więc wiesz, że coś jest nie tak, musisz tylko dowiedzieć się, co i naprawić testy.
Jeśli Twój kod jest dobrze zaprojektowany do testowania jednostkowego, istnieją co najmniej dwa sposoby sprawdzenia, czy dane rzeczywiście zostały poprawnie utrwalone przez testowaną metodę:
wyśmiewaj interfejs bazy danych i pozwól, aby twój próbny zapis, że wywołano w nim odpowiednie funkcje, z oczekiwanymi wartościami. Ta metoda sprawdza, czy metoda wykonuje to, co powinna, i jest klasycznym testem jednostkowym.
przekazać rzeczywistą bazę danych z dokładnie tym samym zamiarem , aby zarejestrować, czy dane zostały poprawnie utrwalone. Ale zamiast mieć wyśmiewaną funkcję, która mówi tylko „tak, mam właściwe dane”, twój test odczytuje bezpośrednio z bazy danych i potwierdza, że jest poprawny. To może nie być najczystszy możliwy test, ponieważ cały silnik bazy danych jest dość dużą rzeczą do napisania uwielbianej makiety, z większą szansą, że przeoczę jakąś subtelność, która sprawia, że test przechodzi pomyślnie, chociaż coś jest nie tak (na przykład ja nie powinienem używać tego samego połączenia z bazą danych do odczytu, co zostało użyte do zapisu, ponieważ mogę zobaczyć niezatwierdzoną transakcję). Ale testuje właściwą rzecz, a przynajmniej wiesz, że to dokładnie implementuje cały interfejs bazy danych bez konieczności pisania fałszywego kodu!
Jest to więc tylko szczegół implementacji testowej, niezależnie od tego, czy czytam dane z testowej bazy danych przez JDBC, czy też kpię z bazy danych. Tak czy inaczej chodzi o to, że mogę lepiej przetestować jednostkę, izolując ją, niż mogę, jeśli pozwolę, by spiskowała z innymi niepoprawnymi metodami w tej samej klasie, aby wyglądała dobrze, nawet jeśli coś jest nie tak. Dlatego chcę użyć wszelkich dogodnych środków, aby sprawdzić, czy poprawne dane zostały utrwalone, innych niż zaufanie komponentowi, którego metodę testuję.
Jeśli Twój kod nie jest dobrze zaprojektowany do testowania jednostkowego, możesz nie mieć wyboru, ponieważ obiekt, którego metodę chcesz przetestować, może nie zaakceptować bazy danych jako wstrzykniętej zależności. W takim przypadku dyskusja na temat najlepszego sposobu odizolowania testowanej jednostki zmienia się w dyskusję na temat tego, jak blisko jest możliwe izolowanie testowanej jednostki. Wniosek jest taki sam. Jeśli możesz uniknąć spisku między wadliwymi jednostkami, robisz to, z zastrzeżeniem dostępnego czasu i wszystkiego, co według ciebie byłoby bardziej skuteczne w wykrywaniu błędów w kodzie.