Closed ianwalter closed 5 years ago
I'm not sure to understand this use case quite well, but I think what you want to do is made possible by spyfs.
import fs from 'fs';
import { vol, fs as memfs } from 'memfs';
import { ufs } from 'unionfs';
import { spy } from 'spyfs';
vol.fromJSON({
'/foo': 'bar',
});
ufs.use(fs).use(memfs);
const sfs = spy(ufs, ({ method, args, resolve, reject }) => {
if (args[0] === '/foo') {
if (method === 'existsSync') resolve(true);
else reject(new Error("Can't touch this!"));
}
});
console.log('existsSync:', sfs.existsSync('/foo'));
try {
console.log('readFileSync:', sfs.readFileSync('/foo'));
} catch (e) {
console.error('readFileSync error:', e.message);
}
The code above will output:
existsSync: true
readFileSync error: Can't touch this!
Is that what you expected?
@pizzafroide Yes, I think it is. Thanks for your help!
This is amazing and works really well for testing because it allows you to mock the filesystem while falling back to the actual filesystem when a path hasn't been mocked, especially for
require
s:But there doesn't seem to be a way to add a file in memfs so that it is mocked and doesn't fall back to the actual filesystem (so it will not be overwritten when tests run) but also does not show up as existing when calling something like
fs.existsSync('foo.txt')
. I would like to propose allowing a user to set a path to something, maybeundefined
, to achieve this:If you use undefined, you'll have to be careful not to run into the specification of a directory using
null
that you added today (thanks again).I hope this doesn't sound too much like an edge case. I think it's pretty important for use in testing.