Faking filesystem access during tests

For ruby there are fakefs and mockfs available to test filesystem operations without even touching the real disk.

The way I’ve seen so far does smell a bit. Everything I’ve seen so far, does rely on creating a clean start-state on disk, running the test, checking if everything has happened as expected and the recreate the clean start-state. They do this for every single test.

I really don’t like this approach, because:

  • Real disc access slows down the tests
  • For a single fileoperation I want to check, probably hundred files are recreated
  • When I add another File that I create during a mix-task, that I alter while processing user input or stuff like that, I need to remember to also add a testcase for this (or multiple), but I can live with that, thats even what testing should do ;), but also I need to remember to stick it into that cleanup/prepare task.
  • When I put files belonging to the project near files or folders that are generated during testrun I have to double check that these aren’t deleted during cleanup. eg, we take a static site generator, which does have some template files under priv/, and also there is some init function which is usually meant to be called from the actual site and not inside of the generator, which does generate some folders and example files below priv/.

To avoid all these hassle, I am searching for alternative workflows or even packages in the fashion of the above mentioned ruby gems.

5 Likes

I didn’t find anything by searching the mailing lists, IRC logs, or GitHub. You may be the first Alchemist to run into this problem :wink: And you may have a new project on your hands.

I did find this cool testing library called shouldi which adds some more conveniences to ExUnit.

2 Likes

Looks like Mock might be useful.

4 Likes

Yeah, found that yesterday as well, but was to tired to actually test it out. So the closer look has to wait another 2 hours or 3, there are things to do…

1 Like

After reading Jose’s post on mocks, I ditched any mocking library and gave a try to modules loaded through config files at compile-time.

Well, I can’t recommend it enough. Extraordinarily clean, simple, and saves you from the async: false curse that mocking libraries bring with themselves, slowing down your test suite.

As an example, here I’m using it exactly as in your case: for accessing a CSV file.

Define a module attribute, reading from the application env (with an optional default value): https://github.com/lucidstack/wdpa-tracker/blob/master/apps/wdpa_importer/lib/wdpa_importer.ex

Create a mock module that handles your test cases: https://github.com/lucidstack/wdpa-tracker/blob/master/apps/wdpa_importer/test/support/file_mock.ex

Configure your application to use the mock in the test environment: https://github.com/lucidstack/wdpa-tracker/blob/master/config/test.exs

Write your tests like there is no tomorrow: https://github.com/lucidstack/wdpa-tracker/blob/master/apps/wdpa_importer/test/wdpa_importer_test.exs

Super-simple, super-efficient, and perhaps arguably elegant too.

7 Likes

Kinda new to Elixir, I too like the approach José outlined. The thing I do not like, or I am missing, is that if you use your config to define an environment specific variable/function/module in “proj_a” then any project that includes your project, say “proj_b”, will have to correctly set its config so that code in “proj_a” that depends on the env settings will access the correct thing.

I do not really understand what you are saying… Can you explain it a bit more detailed?

edit

Nevermind, I just found your other post, I think I do understand better now.

Just found this thread, because I was also looking for some kind ExUnit.FSCase

So… just keeping it warm :smiley:

1 Like