itsok
Mocking system environment variables or alternative
I working on a custom mix task (let’s call it mix update_stuff) that assumes the presence of an environment variable (let’s call it FILE_PATH) that holds a path to a file.
When I test the task, I wish to set the path to a temporary value that is specific to a test. I use ExUnit TmpDir for that, more specifically, I create a temporary file inside tmp_dir and then I wish to set the environment variable only for the context of the test to that file.
I’m not sure how to go about this with ExUnit. I come from Ruby world, where it’s possible to simply stub the value on a test level.
The problem I have seems like a generic problem that most probably many engineers have experienced before, but I can’t find a forum post or a blog post with a solution.
Marked As Solved
al2o3cr
The simplest way I can think of to accommodate that is to make the path in ENV the default while the task still accepts an argument.
This can solve the testing problem: the tests can pass an explicit argument and not share state, but the everyday user doesn’t have to repeat themselves.
Also Liked
itsok
After giving it some thought, this one seems like the most elegant solution.
Thanks everyone who took the time to share your knowledge, much appreciated, I didn’t expect so much feedback, you are a lovely community!
katafrakt
Yes, in Ruby it’s super easy to stub stuff, but it’s not necessarily good. In this case a suggestion to use Application.put_env/4 is of course good, but you are losing the ability to run tests async. Also, I would argue this is not very Elixir-ish way to do things.
I know it’s slightly off-topic, but perhaps you don’t need to keep the file name in an env variable? Environmental variables are to keep things about the environment. I know they are widely used in Ruby as a hack to pass data to commands, but copying tricks from other languages is rarely the best way to do things. You could, for example, just pass the file name as an argument to a mix tasks and the testing this would be trivial.
christhekeele
^ This pattern should be avoided, as the FILE_PATH env var will be read when the code is compiled for production, not in the running production environment itself—for example, using releases, or docker to build your app. runtime.exs should be preferred.







