I'm trying to figure out how to use the Patch decorator (or in general the unittest library) for the following python code (I'm using 3.5 version):
class C:
def __init__(self):
self._session = {'model':'modelName'}
@property
def session(self):
return self._session
from c import C
class A:
def __init__(self):
self.attr_a = C()
from a import A
class B(A):
def foo(self):
model = self.attr_a.session.get('model', '').lower()
print(model)
return model
if __name__ == '__main__':
b = B()
b.foo()
And my (incomplete) code of foo
test is:
import unittest
from b import B
from c import C
from unittest.mock import patch
class TestB(unittest.TestCase):
def setUp(self):
self.b = B()
def test_foo(self, boh):
found = self.b.foo()
expected = 'test'
self.assertEqual(found, expected)
So I don't know how to use mock in this case. In fact I can't even figure out where exactly to create the mock, whether at the level of the variable model
(module B) or at the level of the attr_a
variable (module A). I tried several ideas but but I always get the true value of the model
variable.
Thank you
Solution 1:
Maybe the simplest solution is to use patch.dict on self.b.attr_a.session?
def test_foo(self):
with patch.dict(self.b.attr_a.session, {'model': 'mockedModel'}):
result = self.b.foo()
self.assertEqual(result, 'mockedmodel') # Check if it returns the lowercased model name
In this case I patched the session
dictionary
Solution 2:
@patch('a.C.session', new_callable=PropertyMock)
def test_foo(self, mock_session_prop):
mock_session_prop.return_value = {'model': 'mockedModel'}
result = self.b.foo()
self.assertEqual(result, 'mockedmodel')
In this case I patched the C
class session
as a property