2

I'm struggling with mocking a call of a constructor in an object method that is called by a "procedural" function.

For better understanding here is my code as a short version:

File ./src/b/lambda_function.py:

from src.b.oee_retriever import OeeRetriever

oee_retriever = OeeRetriever()
def handler(event, context):
  return oee_retriever.call_repo()

File ./src/b/oee_retriever.py:

from src.b.oee_repo import OeeRepo
class OeeRetriever():
  oee_repo = None

  def __init__(self):
    self.oee_repo = OeeRepo()
    print('Type: ' + str(type(self.oee_repo)))
  
  def call_repo(self):
    print('calling repo')
    return self.oee_repo.do()

Now I just want to test the lambda_function.handler() function and I want to mock the constructor call OeeRepo() in oee_retriever.__init__()

I tried:

from unittest import TestCase
from unittest.mock import Mock, patch

from src.b.lambda_function import handler

class OeeLambdaFunctionTest(TestCase):

  @patch('src.b.oee_repo.OeeRepo')
  def test_bar(self, oee_repo):
    my_mock = Mock()
    my_mock.do.return_value = 'nope'
    oee_repo.return_value = my_mock

    result = handler(None, None)
    self.assertEqual(result, 'nope')

The mocked result should be 'nope' but the real function oee_repo.do() is called instead. I also tried to use @patch('src.b.oee_retriever.OeeRepo') but the oee_repo.do() was also called in this case.

How can I mock the OeeRepo() constructor call?

Community
  • 1
  • 1
Johnny90
  • 465
  • 1
  • 4
  • 14

1 Answers1

0

Just use patch.object. Here is an example:

from unittest import TestCase
from unittest.mock import patch


class Example:
    def __init__(self) -> None:
        self.name = 'Johnny90'


class Tests(TestCase):
    def test(self):
        # just demo before mock
        self.assertEqual('Johnny90', Example().name)

        def _init_mock(self):
            self.name = 'nope'

        with patch.object(Example, '__init__', _init_mock):
            # after mock
            self.assertEqual('nope', Example().name)

#============================= test session starts #==============================
#collecting ... collected 1 item
#
#debug.py::Tests::test PASSED                                             #[100%]
#
#============================== 1 passed in 2.99s #===============================
Danila Ganchar
  • 10,266
  • 13
  • 49
  • 75