marschall / memoryfilesystem

An in memory implementation of a JSR-203 file system
282 stars 36 forks source link

Example Mocking FileSystems.getDefault() static calls #130

Open ricardojlrufino opened 2 years ago

ricardojlrufino commented 2 years ago

I'm sending you an example, which allows you to use the FileSystems Mock in a transparent way

@Test
    @ExtendWith(MockfsExtension.class)
    void testExecute_MockFSNew(FileSystem fileSystem) throws Exception {

        Path master = Files.createDirectories(Paths.get("/fakedir/conf/java/rest/master"));
        Path homologacao = Files.createDirectories(fileSystem.getPath("/fakedir/conf/java/rest/homologacao"));
        Path dev = Files.createDirectories(fileSystem.getPath("/fakedir/conf/java/rest/dev"));

    }

Paths.get return a mock fs, this is done using Mockito.mockStatic

It's also injecting FileSystem in paramter

using

package br.com.pulse.starter.builder.steps.impl;

import java.nio.file.FileSystem;
import java.nio.file.FileSystems;

import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

import com.github.marschall.memoryfilesystem.MemoryFileSystemBuilder;

public class MockfsExtension implements BeforeEachCallback, AfterEachCallback , ParameterResolver  {

    MockedStatic<FileSystems> mock;

    private FileSystem fileSystem;

    public FileSystem getFileSystem() {
        return this.fileSystem;
    }

    @Override
    public void beforeEach( ExtensionContext context ) throws Exception {
        this.fileSystem = MemoryFileSystemBuilder.newEmpty().build();
        mock = Mockito.mockStatic(FileSystems.class);

        mock.when(() -> FileSystems.getDefault()).then(invocation -> {
            System.out.println("Requested FakeFs >>>");
            return fileSystem;
        });

    }

    @Override
    public void afterEach( ExtensionContext context ) throws Exception {

        if (this.fileSystem != null) {
            this.fileSystem.close();
        }

        mock.close();
    }

    @Override
    public boolean supportsParameter( ParameterContext parameterContext , ExtensionContext extensionContext ) throws ParameterResolutionException {
        return true;
    }

    @Override
    public Object resolveParameter( ParameterContext parameterContext , ExtensionContext extensionContext ) throws ParameterResolutionException {
        return this.fileSystem;
    }

}
marschall commented 2 years ago

Thank you for your submission but I believe injecting a FileSystem instance is a better approach.