bovigo / vfsStream

vfsStream is a stream wrapper for a virtual file system that may be helpful in unit tests to mock the real file system. It can be used with any unit test framework, like PHPUnit or SimpleTest.
BSD 3-Clause "New" or "Revised" License
1.42k stars 102 forks source link

Best practices: using vfsStream methods vs native filesystem methods #281

Closed danepowell closed 1 year ago

danepowell commented 2 years ago

All of the documentation and reference implementations I can find (e.g. Drupal's core tests) use vfsStream methods extensively to mock test fixtures.

But given that the whole point of this library is to mock a functional filesystem, shouldn't best practice be to use native filesystem methods when mocking fixtures? This decouples the choice of filesystem (real, vfs, or something else) from the business logic of fixture setup and is a heck of a lot more concise. For instance:

// Using vfsStream methods.
$root = vfsStream::setup();
vfsStream::newFile('acquia-pipelines.yml')
  ->at($root)
  ->withContent(file_get_contents('acquia-pipelines.yml'));
// Using native filesystem methods.
$root = vfsStream::setup();
copy('acquia-pipelines.yml', $root->url());

These seem functionally identical to me, except the latter is a lot more concise and easier to maintain. Is there any reason one should prefer using vfsStream methods?

bizurkur commented 2 years ago

This is my opinion: Unless you're doing complex tests involving quotas or large files that need to be mocked, there's no reason to use vfsStream methods directly. Call setup() and be done with it. I personally use native methods in my tests for the exact reasons you said - I find it easier to read and maintain. The less a new developer has to learn to update the tests the better.

I will say that I think both of the above examples are not ideal because they are loading data from a real file. Sometimes that may be necessary, but I would avoid it anywhere possible. Mock file systems are nice not only because they don't leave random files laying around but they also avoid disk I/O. However, if you're loading data into the virtual file from a real file you're bringing that disk I/O back into the equation, which slows down the test. If you only have a handful of tests it's likely not a big deal, but if you have hundreds or thousands of tests introducing disk I/O your test suite will suffer.

danepowell commented 2 years ago

Thanks, I totally agree. Good point regarding loading data from real files. In these few tests I think it makes sense, since we're testing input from fairly large and specific yaml and json files. It would be pretty awkward to somehow transcribe and store them in PHP files.