'How to mock an environment variable that is referenced in an imported module?
I have created a file containing environment variables and I am writing a test for this file. The file ("my_variables.py"
) looks like:
import os
if os.getenv("VCAP_APPLICATION"):
foo = os.getenv("foo")
else:
foo = "bar"
In my test I am mocking the definition of the the "VCAP_APPLICATION"
env var. I then assert if my_variables.foo
is equal to "foo"
. This is not the case, as it is equal to "bar"
.
I think my mocked variable is not properly mocked when importing the module. This is why I tried to import the module after mocking my variables. My test looks like this:
import unittest
import os
from unittest.mock import patch
class MyTestCase(unittest.TestCase):
@patch.dict(
os.environ,
{
"VCAP_APPLICATION": "True",
"foo": "foo"
}
)
def test_env_var(self):
print(os.getenv("VCAP_APPLICATION")) # Returns True, so env var is mocked!
import my_variables
self.assertEqual(my_variables.foo, "foo") # Results in AssertionError
Asserting equality results in an AssertionError:
AssertionError: 'Bar' =! 'Foo'
I first had the import at the top of the file. I now placed it after mocking. How can I mock the env var so that my imported module uses that one?
Solution 1:[1]
since the os.getenv()
runs at import time unittest cant mock the object. You're going to have to get hacky by setting the environment variables in the os
module before importing my_variables
:
import unittest
import os
class MyTestCase(unittest.TestCase):
def test_env_var(self):
os.environ["VCAP_APPLICATION"] = "True"
os.environ["foo"] = "foo"
import my_variables
self.assertEqual(my_variables.foo, "foo")
Solution 2:[2]
I used something like this (still i haven't figured out how to solve the import
statement inside test_env_var
).
import os
import unittest
from unittest.mock import patch
class MyTestCase(unittest.TestCase):
@classmethod
def setUpClass(cls):
"""
For future use
"""
super().setUpClass()
your_envs = {
"VCAP_APPLICATION": "True",
"foo": "foo"
}
cls.env = patch.dict(in_dict=os.environ, values=your_envs, clear=True)
cls.env.start()
@classmethod
def tearDownClass(cls):
"""
For future use
"""
super().tearDownClass()
cls.env.stop()
def test_env_var(self):
print(os.getenv("VCAP_APPLICATION")) # Returns True, so env var is mocked!
import my_variables
self.assertEqual(my_variables.foo, "foo") # Results in AssertionError
if __name__ == '__main__':
unittest.main()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | testfile |
Solution 2 | Kots |