Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot monkey patch module variable in Python unit tests

I am trying to test the module:

package/module.py

DATA_PATH = os.path.join(os.path.dirname(__file__), "data")
class SomeClass:
    def __init__(self):
        self.filename = os.path.join(DATA_PATH, "ABC.txt")

in tests/module_test.py I am trying to do

from package import module
@patch("package.module.DATA_PATH", "data_path_here") # doesn't work
class TestSomeClass(unittest.TestCase):
    def setUp(self):
        module.DATA_PATH = "data_path_here" # doesn't work
        self.obj= SomeClass()

    @patch("package.module.DATA_PATH", "data_path_here") # doesn't work either
    def test_constructor(self):
        self.assertEqual(r"data_path_here\ABC.txt", self.obj.filename)

but the DATA_PATH is still not mocked out. I think that I tried all the possible options to mock it out but it still returns original path instead of "data_path_here"

What am I doing wrong?

EDIT: It is not a duplicate of Modifying global variables in Python unittest framework Because that solution does not work

like image 621
Alicja Głowacka Avatar asked May 01 '18 12:05

Alicja Głowacka


2 Answers

You don't need patching since you are using a global variable from another module:

#module.py

DATA_PATH = 1

def getData():
    return DATA_PATH


#tests.py
from package import module

print(module.DATA_PATH, module.getData())
module.DATA_PATH = 2
print(module.DATA_PATH, module.getData())

Output:

1 1
2 2
like image 115
quamrana Avatar answered Sep 23 '22 20:09

quamrana


For me, using mock/patch is a painful exercise. On the other hand, it was trivial to accomplish by setting (and restoring) the global for the tests:

import mock_module

class TestSomeClass(unittest2.TestCase):
    def setUp(self):
        self._original = mock_module.DATA_PATH
        mock_module.DATA_PATH = 'data_path_here'

    def tearDown(self):
        mock_module.DATA_PATH = self._original

    def test_constructor(self):
        obj = mock_module.SomeClass()
        self.assertEqual(r"data_path_here\ABC.txt", obj.filename)

Note that for my os path join, the separator is \ but your usage may differ.

Ran 1 test in 0.005s

OK

like image 44
F1Rumors Avatar answered Sep 21 '22 20:09

F1Rumors