Jest: Build a kick-ass fs mock.

Created on 16 Mar 2017  Â·  23Comments  Â·  Source: facebook/jest

@jeanlauliac mentioned it would be great if Jest could come with a kick-ass fs mock out of the box.

  • This would work well for integration tests.
  • We can potentially provide the same for other data sources (http, sockets etc.)

Goal:

  • Ships as part of Jest, no configuration.
  • Easy way to enable it (Similar to jest.mock('fs')?).
Feature Request good first issue

Most helpful comment

We use metro-memory-fs at the moment for Metro's automated tests, that has proper path resolutions and a few of the core functions we needed. It lacks docs, but it's essentially the same API as fs. It can be used as as such:

jest.mock('fs', () => new (require('metro-memory-fs'))());

beforeEach(() => require('fs').reset());  // optional, cleans up the whole filesystem

It has fairly decent test coverage itself, so contributions are welcome!

All 23 comments

I was thinking about the same thing, this would be great! FS and HTTP requests sound like a great idea

Yes please! As someone who has recently starting with Unit Testing and TDD you guys have made the experience super simple without sacrificing utility. Now that I'm trying to test some related stuff with fs It's starting to become quite complex. Props to you guys for all the work!

Can you explain better what do you guys want to? :)

I think it would be a fully fleshed out implementation of the "fs" library, but built entirely around mocking and stubbing. An example would be how VCR does that for XMLHttpRequest, but for file system access.

There's a few ways it could be done. Perhaps you could provide a dummy "fs" module that lets you use an external API for your files, or you could provide an object of files and reference data (I do this in Forgeries )

@ide has a proposal for this!

In my mind, it'd be great to just have a simple mock API where using fs.writeFile writes to a pure memory filesytem instead of disk, and where fs.readFile allows to read files that have been written as such. Of course everything else would also work on that memory fs, such as fs.createReadStream, fs.open, fs.watch, etc. In practice, tests could write necessary files in beforeEach, call the code to be tested, and possibly verify content of files afterwards.

fs.mockMemoryFS('posix');
const fs = require('fs');
const smth = require('../smth');

it('works', () => {
  fs.writeFileSync('/var/test_file', 'foo');
  smth('/var/test_file');
  expect(fs.readFileSync('/var/test_file', 'utf8')).toMatchSnapshot();
});

We could imagine supporting explicitely posix/win environment no matter the real host OS, and having the mock automatically create traditional posix directories such as /tmp.

(As for sockets/HTTP, that'd be amazing to be able to create a completely virtual network of machines and being able to test client/server interactions, etc.)

Any updates in this one?

Yes please. I've had many issues trying to get mock-fs to play nice with jest.mock. Having it built-in would be great.

There is https://github.com/webpack/memory-fs. I haven't actually tested if sticking it in __mocks__/fs is enough.

We have a pretty good mock here: https://github.com/facebook/metro/blob/master/packages/metro/src/node-haste/__mocks__/fs.js but never had any chance to polish it and pull it out.

The one you mentioned @cpojer lacks many features and has a lot of problems to be fixed; though that was indeed the one I was thinking of reusing after improvements. memory-fs is worth investigating, as it looks feature-complete!

Will it allow me to just Mock parts of the Filesystem and leave the rest
untouched? Primarly i just want to mock a folder and a few files, leaving
the rest untouched. So require works as normal and so on...trying to get
spyfs+memfs to work. But it doesnt seem as easy as i thought...

Jean Lauliac notifications@github.com schrieb am Sa., 2. Dez. 2017, 12:07:

The one you mentioned @cpojer https://github.com/cpojer lacks many
features and has a lot of problems to be fixed. memory-fs looks worth
investigating! ^_^

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/facebook/jest/issues/3154#issuecomment-348684871, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAR612FuAOdzLJsCafEh7BJlnitoXGswks5s8S9ZgaJpZM4Me0Up
.

Will it allow me to just Mock parts of the Filesystem and leave the rest untouched? Primarly i just want to mock a folder and a few files, leaving the rest untouched. So require works as normal and so on...trying to get spyfs+memfs to work. But it doesnt seem as easy as i thought...

I think it's an all or nothing thing. But I think it'll behave like you want, as jest implements require itself, so those would dodge the mocked fs anyways. I'd be curious to hear experiences using memory-fs for tests.

It's under the hood of webpack-dev-server, so pretty well tested. Would be cool if we could just point to it

I've started working on building a high-quality memory FS, I think I'll send a PR sometime next week.

I've looked at the memory-fs package but it doesn't implement the path resolution behaviour as it happens on Linux/BSDs-type machines (that is what I'm targeting as a first step), especially when it comes to symlinks. It is also missing a bunch of pieces of functionality (ex open, lstat, etc.), contrary to what I thought at first.

(A realistic memory FS for Windows might need some adjustments, but that's for later.)

@jeanlauliac i played around with https://github.com/streamich/spyfs and https://github.com/streamich/memfs it was the most promising variant for me.

it did it by spying on the realfs and only intercepting stuff thats defined in the memfs volume...

it worked 98%. if you are interested i can share some code. all other variants failed for one or another reason

@jeanlauliac, @digitalkaoz, @cpojer: Any updates?

Alternatively, it would be great if anyone could share their own fs mocks in the meantime.

We use metro-memory-fs at the moment for Metro's automated tests, that has proper path resolutions and a few of the core functions we needed. It lacks docs, but it's essentially the same API as fs. It can be used as as such:

jest.mock('fs', () => new (require('metro-memory-fs'))());

beforeEach(() => require('fs').reset());  // optional, cleans up the whole filesystem

It has fairly decent test coverage itself, so contributions are welcome!

Do we still think this should be shipped as part of Jest?

A mock file system would be nice if Jest ever had first class support for fixtures.

The Metro one is great. Use metro-memory-fs. It doesn't need to be part of Jest.

it needs to support require('fs').promises; though 😀

Pull Requests welcome!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Antho2407 picture Antho2407  Â·  3Comments

kentor picture kentor  Â·  3Comments

jardakotesovec picture jardakotesovec  Â·  3Comments

samzhang111 picture samzhang111  Â·  3Comments

ianp picture ianp  Â·  3Comments