Mocking súborového systému s Jimfs

1. Prehľad

Pri testovaní komponentov, ktoré intenzívne využívajú I / O operácie, môžu naše testy typicky trpieť niekoľkými problémami, ako je zlý výkon, závislosť od platformy a neočakávaný stav.

V tomto návode sa pozrieme na to, ako môžeme tieto problémy zmierniť pomocou systému súborov Jimfs v pamäti.

2. Úvod do Jimfs

Jimfs je systém súborov v pamäti, ktorý implementuje rozhranie Java NIO API a podporuje takmer všetky jeho funkcie. To je obzvlášť užitočné, pretože to znamená, že môžeme emulovať virtuálny súborový systém v pamäti a komunikovať s ním pomocou nášho existujúceho java.nio vrstva.

Ako uvidíme, môže byť výhodné použiť falošný súborový systém namiesto skutočného na:

  • Vyhnite sa závislosti na súborovom systéme, ktorý momentálne vykonáva test
  • Zaistite, aby bol súborový systém pri každom testovaní zostavený s očakávaným stavom
  • Pomôžte nám urýchliť testy

Pretože súborové systémy sa značne líšia, použitie Jimfs tiež uľahčuje ľahké testovanie so súborovými systémami z rôznych operačných systémov.

3. Závislosti Maven

Najskôr pridajme závislosti projektu, ktoré budeme potrebovať pre svoje príklady:

 com.google.jimfs jimfs 1.1 

Závislosť jimfs obsahuje všetko, čo potrebujeme, aby sme mohli používať náš zosmiešňovaný súborový systém. Ďalej budeme písať testy pomocou JUnit5.

4. Jednoduché úložisko súborov

Začneme definíciou jednoduchého FileRepository trieda, ktorá implementuje niektoré štandardné operácie CRUD:

verejná trieda FileRepository {void create (cesta, reťazec fileName) {cesta filePath = cesta.resolve (názov súboru); skus {Files.createFile (filePath); } catch (IOException ex) {throw new UncheckedIOException (ex); }} Čítanie reťazca (cesta k ceste) {try {return new String (Files.readAllBytes (cesta)); } catch (IOException ex) {throw new UncheckedIOException (ex); }} Aktualizácia reťazca (cesta cesty, reťazec newContent) {try {Files.write (cesta, newContent.getBytes ()); návrat newContent; } catch (IOException ex) {throw new UncheckedIOException (ex); }} void delete (Cesta cesty) {try {Files.deleteIfExists (cesta); } catch (IOException ex) {throw new UncheckedIOException (ex); }}}

Ako vidíme, každá metóda využíva štandard java.nio triedy.

4.1. Vytvorenie súboru

V tejto časti napíšeme test, ktorý testuje vytvoriť metóda z nášho úložiska:

@Test @DisplayName ("Malo by sa vytvoriť súbor v súborovom systéme") void givenUnixSystem_whenCreatingFile_thenCreatedInPath () {FileSystem fileSystem = Jimfs.newFileSystem (Configuration.unix ()); Reťazec fileName = "newFile.txt"; Cesta pathToStore = fileSystem.getPath (""); fileRepository.create (pathToStore, fileName); assertTrue (Files.exists (pathToStore.resolve (fileName))); }

V tomto príklade sme použili statický metóda Jimfs.newFileSystem () vytvoriť nový systém súborov v pamäti. Míňame konfiguračný objekt Configuration.unix (), ktorá vytvára nemennú konfiguráciu pre súborový systém Unix. Patria sem dôležité informácie špecifické pre OS, ako sú oddeľovače ciest a informácie o symbolických odkazoch.

Teraz, keď sme vytvorili súbor, môžeme skontrolovať, či bol súbor úspešne vytvorený v systéme založenom na systéme Unix.

4.2. Čítanie súboru

Ďalej otestujeme metódu, ktorá načíta obsah súboru:

@Test @DisplayName ("Mal by čítať obsah súboru") void givenOSXSystem_whenReadingFile_thenContentIsReturned () vyvolá výnimku {FileSystem fileSystem = Jimfs.newFileSystem (Configuration.osX ()); Cesta resourceFilePath = fileSystem.getPath (RESOURCE_FILE_NAME); Files.copy (getResourceFilePath (), resourceFilePath); Reťazec content = fileRepository.read (resourceFilePath); assertEquals (FILE_CONTENT, obsah); }

Tentokrát sme skontrolovali, či je možné prečítať obsah súboru v a systém macOS (predtým OSX) jednoduchým použitím iného typu konfigurácie - Jimfs.newFileSystem (Configuration.osX ()).

4.3. Aktualizácia súboru

Môžeme tiež použiť Jimfs na otestovanie metódy, ktorá aktualizuje obsah súboru:

@Test @DisplayName ("Mal by aktualizovať obsah súboru") void givenWindowsSystem_whenUpdatingFile_thenContentHasChanged () vyvolá výnimku {FileSystem fileSystem = Jimfs.newFileSystem (Configuration.windows ()); Cesta resourceFilePath = fileSystem.getPath (RESOURCE_FILE_NAME); Files.copy (getResourceFilePath (), resourceFilePath); String newContent = "Aktualizujem vás."; Reťazec content = fileRepository.update (resourceFilePath, newContent); assertEquals (newContent, content); assertEquals (newContent, fileRepository.read (resourceFilePath)); }

Rovnako sme tentokrát skontrolovali, ako sa metóda správa v a Systém založený na systéme Windows pomocou Jimfs.newFileSystem (Configuration.windows ()).

4.4. Vymazanie súboru

Na záver testovania našich operácií CRUD otestujme metódu, ktorá odstráni súbor:

@Test @DisplayName ("Mal by vymazať súbor") void givenCurrentSystem_whenDeletingFile_thenFileHasBeenDeleted () vyvolá výnimku {FileSystem fileSystem = Jimfs.newFileSystem (); Cesta resourceFilePath = fileSystem.getPath (RESOURCE_FILE_NAME); Files.copy (getResourceFilePath (), resourceFilePath); fileRepository.delete (resourceFilePath); assertFalse (Files.exists (resourceFilePath)); }

Na rozdiel od predchádzajúcich príkladov sme použili Jimfs.newFileSystem () bez zadania konfigurácie súborového systému. V takom prípade Jimfs vytvorí nový systém súborov v pamäti s predvolenou konfiguráciou zodpovedajúcou aktuálnemu operačnému systému.

5. Presun súboru

V tejto časti sa dozvieme, ako otestovať metódu, ktorá presúva súbor z jedného adresára do druhého.

Po prvé, poďme implementovať pohnúť sa metóda využívajúca štandard java.nio.file.File trieda:

void move (Path origin, Path destination) {try {Files.createDirectories (destination); Files.move (origin, destination, StandardCopyOption.REPLACE_EXISTING); } catch (IOException ex) {throw new UncheckedIOException (ex); }}

Použijeme parametrizovaný test, aby sme sa uistili, že táto metóda funguje na niekoľkých rôznych súborových systémoch:

private static Stream provideFileSystem () {return Stream.of (Arguments.of (Jimfs.newFileSystem (Configuration.unix ())), Arguments.of (Jimfs.newFileSystem (Configuration.windows ())), Arguments.of (Jimfs. newFileSystem (Configuration.osX ()))); } @ParameterizedTest @DisplayName ("Mal by presunúť súbor do nového cieľa") @MethodSource ("provideFileSystem") void givenEachSystem_whenMovingFile_thenMovedToNewPath (FileSystem fileSystem) vyvolá výnimku {Cesta pôvod = fileSystem.getPath (RESOUR_NAME) Files.copy (getResourceFilePath (), pôvod); Cieľ cesty = fileSystem.getPath ("newDirectory", RESOURCE_FILE_NAME); fileManipulation.move (pôvod, cieľ); assertFalse (Files.exists (origin)); assertTrue (Files.exists (cieľ)); }

Ako vidíme, pomocou Jimfs sme tiež mohli otestovať, že z jedného prístroja môžeme presúvať súbory na rôznych rôznych súborových systémoch.

6. Testy závislé od operačného systému

Aby sme demonštrovali ďalšiu výhodu používania Jimfs, vytvorme a FilePathReader trieda. Trieda je zodpovedná za vrátenie skutočnej systémovej cesty, ktorá je samozrejme závislá od OS:

trieda FilePathReader {String getSystemPath (cesta cesty) {try {návratová cesta .toRealPath () .toString (); } catch (IOException ex) {throw new UncheckedIOException (ex); }}}

Teraz pridajme test pre túto triedu:

class FilePathReaderUnitTest {private static String DIRECTORY_NAME = "baeldung"; private FilePathReader filePathReader = nový FilePathReader (); @Test @DisplayName ("Mal by získať cestu v systéme Windows") void givenWindowsSystem_shouldGetPath_thenReturnWindowsPath () vyvolá výnimku {FileSystem fileSystem = Jimfs.newFileSystem (Configuration.windows ()); Cesta cesty = getPathToFile (fileSystem); Reťazec stringPath = filePathReader.getSystemPath (cesta); assertEquals ("C: \ work \" + DIRECTORY_NAME, stringPath); } @Test @DisplayName ("Mal by dostať cestu k unixu") void givenUnixSystem_shouldGetPath_thenReturnUnixPath () vyvolá výnimku {FileSystem fileSystem = Jimfs.newFileSystem (Configuration.unix ()); Cesta cesty = getPathToFile (fileSystem); Reťazec stringPath = filePathReader.getSystemPath (cesta); assertEquals ("/ work /" + DIRECTORY_NAME, stringPath); } súkromná cesta getPathToFile (FileSystem fileSystem) vyvolá výnimku {cesta cesty = fileSystem.getPath (DIRECTORY_NAME); Files.createDirectory (cesta); spiatočná cesta; }}

Ako vidíme, výstup pre Windows sa líši od výstupu pre Unix, ako by sme čakali. Navyše, nemuseli sme tieto testy spúšťať pomocou dvoch rôznych súborových systémov - Jimfs to za nás vysmieval automaticky.

Za zmienku to stojí Jimfs nepodporuje vyplniť() metóda, ktorá vracia a java.io.Súbor. Je to jediná metóda z Cesta trieda, ktorá nie je podporovaná. Preto by mohlo byť lepšie pracovať na InputStream skôr ako a Súbor.

7. Záver

V tomto článku sme sa naučili, ako používať fiktívne interakcie súborového systému Jimfs pomocou našich jednotkových testov.

Najskôr sme začali definovaním jednoduchého úložiska súborov s niekoľkými operáciami CRUD. Potom sme videli príklady toho, ako každú z metód otestovať pomocou iného typu súborového systému. Na záver sme videli príklad toho, ako môžeme pomocou Jimfs otestovať prácu so súborovým systémom závislým od OS.

Ako vždy, kód týchto príkladov je k dispozícii na stránkach Github.


$config[zx-auto] not found$config[zx-overlay] not found