Reputation: 637
I have a problem about figuring out paths when using mock in Python.
Suppose, that i have the following files
file1.py
def func1():
return 'X'
file2.py
from file1 import func1
class ClassA():
def func_that_uses_func1(self):
x = func1()
How could I patch the usage of func1 on ClassA? I have tried @mock.patch('file2.func1'), but i get an the error AttributeError: <class 'ClassA'> does not have the attribute 'func1'
Upvotes: 15
Views: 15904
Reputation: 2968
The guidance & examples at https://docs.python.org/3/library/unittest.mock.html#where-to-patch are helpful. Headline:
The basic principle is that you patch where an object is looked up, which is not necessarily the same place as where it is defined.
Upvotes: 0
Reputation: 31
For your "had to use the real path" problem, you just need write the path from the lowest common ancestor of test file and the file you want to import.
If you want to use imported module instead of string format, I recommend you to use patch.object
.
Upvotes: 3
Reputation: 26586
I think you want to actually do your mock as @mock.patch('file2.func1')
. My example below might help:
from file2 import ClassA
from mock import patch
import unittest
class TestClassA(unittest.TestCase):
def setUp(self):
self.c = ClassA()
@patch('file2.func1')
def test_func(self, m_func1):
self.c.func_that_uses_func1()
self.assertEqual(m_func1.called, 1)
if __name__ == '__main__':
unittest.main()
Upvotes: 11