5

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

3
  • Possible duplicate of Modifying global variables in Python unittest framework Commented May 1, 2018 at 13:44
  • it is not a duplicate because that solution does not work Commented May 1, 2018 at 14:16
  • You might want to confirm a forward vs back slash issue on the test ... is the path really separated with a \ or a / ?? That would make the "assignment" approach in the setup work. Commented May 1, 2018 at 14:52

2 Answers 2

5

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
Sign up to request clarification or add additional context in comments.

4 Comments

this is better and cleaner without mocking.
amazing, thank you. I had to import the module and change the value on the module as you've done. e.g. import module and module.var = <some_val>. from module import var and then setting var = <some_val> did not make a persistent change.
When you use from module import var and then var = something you are only using your own module's var and you don't affect module.var. Mandatory link to Ned Batchelder
This should be the correct answer, works for my case!
2

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.