Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Mock FileSystem function

I do not know how to mock the section where I'm changing the file's owner from line Path path = newFile.toPath(); to the end.

Here's my function :

@RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public String uploadEndpoint(@RequestParam("file") MultipartFile file,
                                 @RequestParam("usernameSession") String usernameSession,
                                 @RequestHeader("current-folder") String folder) throws IOException {


        String[] pathArray = file.getOriginalFilename().split("[\\\\\\/]");
        String originalName = pathArray[pathArray.length-1];
        LOGGER.info("Upload triggerred with : {} , filename : {}", originalName, file.getName());
        String workingDir = URLDecoder.decode(folder.replace("!", "."),
                StandardCharsets.UTF_8.name())
                .replace("|", File.separator);
        LOGGER.info("The file will be moved to : {}", workingDir);
        File newFile = new File(workingDir + File.separator + originalName);
        //UserPrincipal owner = Files.getOwner(newFile.toPath());

        file.transferTo(newFile);

        Path path = newFile.toPath();
        FileOwnerAttributeView foav = Files.getFileAttributeView(path, FileOwnerAttributeView.class);
        UserPrincipal owner = foav.getOwner();
        System.out.format("Original owner  of  %s  is %s%n", path, owner.getName());

        FileSystem fs = FileSystems.getDefault();
        UserPrincipalLookupService upls = fs.getUserPrincipalLookupService();

        UserPrincipal newOwner = upls.lookupPrincipalByName(usernameSession);
        foav.setOwner(newOwner);

        UserPrincipal changedOwner = foav.getOwner();
        System.out.format("New owner  of  %s  is %s%n", path,
                changedOwner.getName());

        return "ok";
    }

And here's the test :

@Test
    public void uploadEndpointTest() throws Exception {
        PowerMockito.whenNew(File.class).withAnyArguments().thenReturn(file);
        Mockito.when(multipartFile.getOriginalFilename()).thenReturn("src/test/resources/download/test.txt");
        assertEquals("ok", fileExplorerController.uploadEndpoint(multipartFile, "userName", "src/test/resources/download"));
    }

I got an exception because "userName" is not a user. I'd like to mock the call where it looks for a match in windows's users. It works when I set my window's username instead of "userName", but I can't let my window's username.

I tried to mock fs.getUserPrincipalLookupService(); and upls.lookupPrincipalByName(usernameSession); but I do not know what to return to mock the call.

Many thanks !

like image 564
Majestic Avatar asked Nov 17 '25 04:11

Majestic


1 Answers

First of all, you should consider the Single Responsibility principle and further dissect your code.

Meaning: create a helper class that abstracts all these low level file system accesses for you. Then you provide a mocked instance of that helper class here, and you simply ensure that the helper method gets called with the expected parameters. That will make your service method uploadEndpoint() much easier to test.

And then, your new helper class could simply expect a File object. And that enables you to pass a mocked File object to it, and all of a sudden you are in control of what thatMockedFileObject.newPath() will return.

In other words: your first goal should be to write code that doesn't make use of static or new() in a way that prevents simple mocking using Mockito. Whenever you encounter situations where you think "I need PowerMock(ito) to test my production code", then the very first impulse should be: "I should avoid that, and improve my design".

Same for FileSystem fs = FileSystems.getDefault(); ... instead of trying to get into the "mock that static call business", you make sure that your helper classes accept some FileSystem instance. And all of a sudden you can pass a simple Mockito mock object, and you are in full control over it.

like image 134
GhostCat Avatar answered Nov 19 '25 19:11

GhostCat