Mocking a global variable Mocking a global variable python python

Mocking a global variable


Variables can be patched as follows:

from mock import patch@patch('module.variable', new_value)    

For example:

import alphabetfrom mock import patch@patch('alphabet.letters', ['a', 'b', 'c'])class TestAlphabet():    def test_length_letters(self):        assert 3 == alphabet.length_letters()    def test_contains_letter(self):       assert alphabet.contains_letter('a')


Try this:

import unittests  import alphabet   from unittest import mock class TestAlphabet(unittest.TestCase):     def setUp(self):        self.mock_letters = mock.patch.object(            alphabet, 'letters', return_value=['a', 'b', 'c']        )    def test_length_letters(self):        with self.mock_letters:            self.assertEqual(3, alphabet.length_letters())    def test_contains_letter(self):        with self.mock_letters:            self.assertTrue(alphabet.contains_letter('a'))

You need to apply the mock while the individual tests are actually running, not just in setUp(). We can create the mock in setUp(), and apply it later with a with ... Context Manager.


I ran into a problem where I was trying to mock out variables that were used outside of any function or class, which is problematic because they are used the moment you try to mock the class, before you can mock the values.

I ended up using an environment variable. If the environment variable exists, use that value, otherwise use the application default. This way I could set the environment variable value in my tests.

In my test, I had this code before the class was imported

os.environ["PROFILER_LOG_PATH"] = "./"

In my class:

log_path = os.environ.get("PROFILER_LOG_PATH",config.LOG_PATH)

By default my config.LOG_PATH is /var/log/<my app name>, but now when the test is running, the log path is set to the current directory. This way you don't need root access to run the tests.