Przedstawiam testy w projekcie, który intensywnie wykorzystuje operacje IO (w tym przypadku system plików). System stale otwiera / zamyka pliki, sprawdza, czy pliki istnieją, usuwa je itp.
Szybko stało się oczywiste, że regularne kpiny nie przydałyby się zbytnio, ponieważ utrudniłoby mi konfigurację testów i uzasadnienie. Z drugiej strony posiadanie fałszywego systemu plików byłoby niesamowite i myślę, że całkiem łatwe w konfiguracji.
Wygląda na to, że kolesie z Rubiego zrobili to ponownie i właśnie o to proszę w rubim: http://ozmm.org/posts/fakefs.html .
Czy jest coś zdalnie podobnego dla Javy?
java
unit-testing
testing
mocking
pożarł elizjum
źródło
źródło
Odpowiedzi:
Google ma otwartą implementację w pamięci oprogramowania FileSystemProvider Java 7. Projekt nazywa jimfs .
Jeśli używasz Java 6 lub wcześniejszej, istnieje alternatywa: wcześniej używałem Apache Commons VFS, aby osiągnąć wielki sukces. Wygląda na to, że jest bardzo podobny do niestandardowego FileSystemProvider, inny wspomniany odpowiadający jest w Javie 7.
Jest wstępnie załadowany z kilkoma implementacjami systemu plików: Plik, RAM, S / FTP i Jar, aby wymienić tylko kilka. Widziałem też wtyczkę dla S3 .
źródło
Path
przypadkowo)W Javie 6 i wcześniejszych jest to trudne, ponieważ klasy takie jak
File
iFileInputStream
nie zapewniają możliwości wysyłania do różnych „wirtualnych systemów plików” w przestrzeni Java.W Javie 7 dostępna jest obsługa wirtualnych systemów plików; zobacz Tworzenie niestandardowego dostawcy systemu plików . Nie wiem, czy to pozwoli ci robić to, co chcesz, ale to dobre miejsce, aby zacząć szukać.
Właściwie wygrywasz używając FileSystemProvider:
Wdrażasz coś, co (jeśli jest wydane na licencji open source) może być bardzo przydatne dla innych osób na twoim stanowisku i do innych celów.
Ułatwisz sobie to, jeśli zdecydujesz się przełączyć na dostawcę FileSystemProvider, nad którym może teraz pracować ktoś inny.
źródło
Możesz użyć
org.junit.rules.TemporaryFolder
z pakietu JUnit :Przykład:
final TemporaryFolder testFolder = new TemporaryFolder(); testFolder.create(); final Path filePath = testFolder.newFile("input.txt").toPath(); final Path dirPath = testFolder.newFolder("subfolder").toPath();
Alternatywnie zrezygnuj z
.toPath()
części:final File filePath = testFolder.newFile("input.txt");
źródło
Możesz wyodrębnić użycie programu
File
, używając zamiaru „gdzieś do zapisu danych”, zmieniając interfejs API tak, aby używałOutputStream
zamiast aFile
, a następnie przekazać API aFileOutputStream
w kodzie produkcyjnym, ale przekaż jeByteArrayOutputStream
z testów. AByteArrayOutputStream
jest strumieniem w pamięci, więc jest bardzo szybki i możesz po prostu sprawdzić jego zawartość za pomocą jego metod - jest idealny do testowania. Jest też odpowiedni,ByteArrayInputStream
jeśli chcesz odczytać dane.Systemy plików są generalnie dość szybkie - nie zawracałbym sobie tym głowy, chyba że robisz dużo operacji we / wy plików w swoich testach.
Należy pamiętać, że tworzenie java
File
obiekt ma nie utworzyć plik na dysku, to poniższy kod nie powoduje żadnych zmian na dysku:File f = new File("somepath"); // doesn't create a file on disk
źródło
new File("xyz").getAbsolutePath()
ma absolutnie nic wspólnego except powrócić na ścieżkę, że plik będzie mieć gdyby istniał. Nie zmienia systemu plików; jeśli plik nie istnieje, nadal zwraca ciąg ścieżki i nie tworzy pliku. Co miałeś na myśli mówiąc „zobacz, co się stanie”?File
nie jest ostateczna w moim OpenJDK 7.Jimfs od Google to system plików NIO w pamięci, który świetnie nadaje się do testów.
źródło
Prostym sposobem byłoby użycie systemu plików opartego całkowicie na pamięci RAM - tempfs w systemie Linux, dysk RAM w systemie Windows.
źródło
Wygląda na to, że MockFTPServer ma kilka implementacji fałszywego systemu plików (Unix / Windows)
Wygląda na to, że możesz używać tych fałszywych implementacji systemu plików całkiem oddzielnie od wszelkich koncepcji FTP. Próbuję tego teraz w dokładnie tych samych celach, które opisałeś.
źródło
Nie jestem pewien co do konkretnych frameworków, ale ogólnym podejściem w zakresie OOP byłoby napisanie kilku abstrakcyjnych warstw na wierzchu dowolnego kodu dostępu do pliku (bród interfejsów!) i być może fasadę ułatwiającą korzystanie z typowych operacji. następnie po prostu mockujesz jedną warstwę poniżej kodu, który aktualnie testujesz, i jest to zasadniczo fałszywy system plików (a przynajmniej kod, który testujesz, nie będzie wiedział inaczej).
Jeśli przyjrzysz się użyciu struktury iniekcji zależności, aby poradzić sobie z tym za Ciebie, ułatwi to możliwość przełączania komponentów na fałszywą implementację interfejsu. Jeśli zastosujesz się do wzorców odwrócenia kontroli, przekazanie wszelkich zależności do konstruktora klasy, którą testujesz, również ułatwi testowanie.
public interface IFileSystem { IFileHandle Load(string path); //etc } public class ClassBeingTested { public ClassBeingTested(IFileSystem fileSystem) { //assign to private field } public void DoSomethingWithFileSystem() { //utilise interface to file system here //which you could easily mock for testing purposes //by passing a fake implementation to the constructor } }
Mam nadzieję, że moja java jest poprawna, nie pisałem javy przez długi czas, ale mam nadzieję, że zrozumiesz dryf. mam nadzieję, że nie lekceważę tego problemu i jestem zbyt uproszczony!
oczywiście to wszystko przy założeniu, że masz na myśli prawdziwe testowanie jednostkowe, to znaczy testowanie najmniejszych możliwych jednostek kodu, a nie całego systemu. do testowania integracji potrzebne jest inne podejście.
źródło
Wygląda na to, że ShrinkWrap z projektu Arquillian zawiera w pamięci FileSystem zgodny z NIO
Możesz utworzyć prosty system plików w pamięci, wykonując następujące czynności:
źródło
Dwa inne systemy plików pamięci dla Java to:
system plików pamięci
efemeralfy
Oba implementują interfejs API systemu plików NIO.2.
źródło
Wyszukałem w Google „Fake java FileSystem” i znalazłem to pytanie. Niestety to wszystko, co znalazłem. Więc sam napisałem ten fałszywy system plików: https://github.com/dernasherbrezon/mockfs
Używam go do symulacji IOExceptions podczas odczytu / zapisu do plików. IOException może wystąpić na przykład z powodu „braku miejsca na dysku”, co jest prawie niemożliwe do zasymulowania innymi sposobami.
źródło
Jest trochę stare i wydaje się, że to rozwiązanie tylko dla systemu Linux, ale wygląda dobrze https://www.google.co.il/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=tmpfs%20on% 20ubuntu
tmpfs to katalog mapowany w pamięci (dane znikają po ponownym uruchomieniu). Po zamontowaniu dane mogą być do niego kopiowane i przetwarzane z pamięci.
źródło