Czy są jakieś biblioteki lub metody do makiety systemu plików w C # do pisania testów jednostkowych? W moim obecnym przypadku mam metody, które sprawdzają, czy dany plik istnieje i odczytują datę utworzenia. W przyszłości mogę potrzebować czegoś więcej.
c#
unit-testing
mocking
pupeno
źródło
źródło
Odpowiedzi:
Edycja: zainstaluj pakiet NuGet
System.IO.Abstractions
.Ten pakiet nie istniał, gdy pierwotnie zaakceptowano tę odpowiedź. Oryginalna odpowiedź jest podana poniżej w kontekście historycznym:
źródło
Ta wyimaginowana biblioteka istnieje teraz, istnieje pakiet NuGet dla System.IO.Abstractions , który wyodrębnia przestrzeń nazw System.IO.
Istnieje również zestaw pomocników testowych, System.IO.Abstractions.TestingHelpers, który - w momencie pisania - jest tylko częściowo zaimplementowany, ale jest bardzo dobrym punktem wyjścia.
źródło
Prawdopodobnie będziesz musiał zbudować kontrakt, aby określić, czego potrzebujesz z systemu plików, a następnie napisać opakowanie wokół tych funkcji. W tym momencie będziesz w stanie kpić z implementacji lub ją zablokować.
Przykład:
źródło
Zalecam użycie http://systemwrapper.codeplex.com/, ponieważ zapewnia on otoki dla najczęściej używanych typów w przestrzeni nazw System
źródło
Natknąłem się na następujące rozwiązania tego problemu:
W końcu używam wszystkich powyższych metod, w zależności od tego, co piszę. Ale przez większość czasu myślę, że abstrakcja jest zła, kiedy piszę testy jednostkowe, które trafiają w IO.
źródło
Używając System.IO.Abstractions i System.IO.Abstractions.TestingHelpers w ten sposób:
W swojej klasie testowej używasz MockFileSystem () do mockowania pliku i instalujesz ManageFile jak:
źródło
Możesz to zrobić za pomocą Microsoft Fakes bez konieczności zmiany bazy kodu, na przykład ponieważ została już zamrożona.
Najpierw wygeneruj fałszywy zestaw dla System.dll - lub dowolnego innego pakietu, a następnie udawaj oczekiwane zwroty, jak w:
źródło
Trudno byłoby sfałszować system plików w teście, ponieważ interfejsy API plików .NET nie są tak naprawdę oparte na interfejsach lub rozszerzalnych klasach, które można by pozorować.
Jeśli jednak masz własną warstwę funkcjonalną, aby uzyskać dostęp do systemu plików, możesz kpić z tego w teście jednostkowym.
Jako alternatywę dla mockowania rozważ po prostu utworzenie folderów i plików, których potrzebujesz w ramach konfiguracji testowej, i usunięcie ich metodą dezaktywacji.
źródło
Nie jestem pewien, jak utworzyłbyś makietę systemu plików. To, co możesz zrobić, to napisać konfigurację urządzenia testowego, która tworzy folder itp. Z niezbędną strukturą do testów. Metoda zniszczenia wyczyściłaby go po zakończeniu testów.
Zmieniono, by dodać: myśląc o tym trochę więcej, nie sądzę, abyś chciał kpić z systemu plików, aby przetestować tego typu metody. Jeśli kpisz z systemu plików, aby zwrócić prawdę, jeśli określony plik istnieje, i użyjesz tego w swoim teście metody, która sprawdza, czy ten plik istnieje, to nie testujesz zbyt wiele. Mockowanie systemu plików byłoby przydatne, gdybyś chciał przetestować metodę, która była zależna od systemu plików, ale aktywność systemu plików nie była integralna z testowaną metodą.
źródło
Odpowiadając na twoje konkretne pytanie: Nie, nie ma bibliotek, które pozwolą ci na mockowanie wywołań we / wy plików (o których wiem). Oznacza to, że „prawidłowe” testowanie jednostek typów będzie wymagało uwzględnienia tego ograniczenia podczas definiowania typów.
Krótka uwaga na temat tego, jak definiuję „właściwy” test jednostkowy. Uważam, że testy jednostkowe powinny potwierdzić, że otrzymujesz oczekiwane dane wyjściowe (np. Wyjątek, wywołanie metody itp.) Pod warunkiem, że znane dane wejściowe. Umożliwia to skonfigurowanie warunków testu jednostki jako zestawu wejść i / lub stanów wejściowych. Najlepszym sposobem, jaki znalazłem, jest użycie usług opartych na interfejsach i iniekcji zależności, tak aby każda odpowiedzialność zewnętrzna w stosunku do typu była dostarczana za pośrednictwem interfejsu przekazanego przez konstruktor lub właściwość.
Mając to na uwadze, wracając do pytania. Kpiłem z wywołań systemu plików, tworząc
IFileSystemService
interfejs wraz zFileSystemService
implementacją, która jest po prostu fasadą metod systemu plików mscorlib. Mój kod używa następnieIFileSystemService
typów zamiast mscorlib. Dzięki temu mogę podłączyć mój standard,FileSystemService
gdy aplikacja jest uruchomiona lub udawaćIFileSystemService
w moich testach jednostkowych. Kod aplikacji jest taki sam, niezależnie od tego, jak działa, ale podstawowa infrastruktura umożliwia łatwe testowanie tego kodu.Przyznaję, że używanie opakowania wokół obiektów systemu plików mscorlib jest uciążliwe, ale w tych konkretnych scenariuszach warto wykonać dodatkową pracę, ponieważ testowanie staje się znacznie łatwiejsze i bardziej niezawodne.
źródło
Tworzenie interfejsu i mockowanie go do testowania to najczystszy sposób. Jednak jako alternatywę możesz przyjrzeć się frameworkowi Microsoft Moles .
źródło
Typowym rozwiązaniem jest użycie abstrakcyjnego API systemu plików (takiego jak Apache Commons VFS dla Java): cała logika aplikacji używa API, a testy jednostkowe są w stanie symulować prawdziwy system plików z implementacją stub (emulacja w pamięci lub coś w tym rodzaju).
Dla C # istnieje podobny interfejs API: NI.Vfs, który jest bardzo podobny do Apache VFS V1. Zawiera domyślne implementacje zarówno dla lokalnego systemu plików, jak i systemu plików w pamięci (ostatnia z nich może być używana w testach jednostkowych z pudełka).
źródło
Obecnie używamy zastrzeżonego silnika danych, a jego API nie jest ujawniane jako interfejsy, więc prawie nie możemy testować jednostkowo naszego kodu dostępu do danych. Potem poszedłem z podejściem Matta i Josepha.
źródło
Poszedłbym z odpowiedzią Jamiego Ide. Nie próbuj kpić z rzeczy, których nie napisałeś. Będą różne zależności, o których nie wiedziałeś - zamknięte klasy, niewirtualne metody itp.
Innym podejściem byłoby owinięcie odpowiednich metod czymś, co jest do podrobienia. np. utwórz klasę o nazwie FileWrapper, która umożliwia dostęp do metod File, ale jest czymś, co można wyszydzić.
źródło