Search code examples
pythoninheritancemockingpython-unittest

How to mock in python an inherited attribute that contains the reference to an object


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

  • 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