Piszę komponent, który mając plik ZIP, musi:
- Rozpakuj plik.
- Znajdź konkretną bibliotekę dll wśród rozpakowanych plików.
- Załaduj tę bibliotekę dll przez odbicie i wywołaj na niej metodę.
Chciałbym przetestować jednostkowo ten komponent.
Kusi mnie, aby napisać kod, który zajmuje się bezpośrednio systemem plików:
void DoIt()
{
Zip.Unzip(theZipFile, "C:\\foo\\Unzipped");
System.IO.File myDll = File.Open("C:\\foo\\Unzipped\\SuperSecret.bar");
myDll.InvokeSomeSpecialMethod();
}
Ale ludzie często mówią: „Nie pisz testów jednostkowych, które opierają się na systemie plików, bazie danych, sieci itp.”
Gdybym napisał to w sposób przyjazny dla testów jednostkowych, przypuszczam, że wyglądałoby to tak:
void DoIt(IZipper zipper, IFileSystem fileSystem, IDllRunner runner)
{
string path = zipper.Unzip(theZipFile);
IFakeFile file = fileSystem.Open(path);
runner.Run(file);
}
Yay! Teraz jest to testowalne; Mogę karmić testowymi dublami (próbami) metodą DoIt. Ale jakim kosztem? Musiałem teraz zdefiniować 3 nowe interfejsy, aby było to testowalne. A co dokładnie testuję? Testuję, czy mój DoIt działa poprawnie z jego zależnościami. Nie sprawdza, czy plik zip został poprawnie rozpakowany itp.
Nie wydaje mi się, żebym już testował funkcjonalność. Mam wrażenie, że właśnie testuję interakcje w klasie.
Moje pytanie brzmi : jaki jest właściwy sposób testowania jednostkowego czegoś, co jest zależne od systemu plików?
edytuj Używam .NET, ale koncepcja może również zastosować Java lub kod natywny.
myDll.InvokeSomeSpecialMethod();
, byłoby sprawdzenie, czy działa poprawnie zarówno w sytuacjach sukcesu, jak i niepowodzenia, więc nie przeprowadzałbym testów jednostkowych, DoIt
ale DllRunner.Run
powiedziałbym, że niewłaściwe użycie testu UNIT do podwójnego sprawdzenia, czy cały proces działa, byłoby dopuszczalne niewłaściwe użycie i ponieważ byłby to test integracyjny