Paul
Paul

Reputation: 6737

Mock a method of already instantiated object

I writing unit tests and for testing I want to mock a method of already existing object. But looks like with asyncio corutines it is not so simple as it looks. I tried to use MagickMock but it just doesn't work. There is no errors or exceptions, but with debugger I can see that f() is never being called.

My tests and object I want to patch look like this:

from unittest.mock import patch, MagicMock

class Service(object):
   async def callback_handler(self, msg):
      pass

   async def handle(self, msg):
      await self.callback_handler(msg)

class TestCase(object):
    def setUp(self):
      self.service = Service()

    @patch('module.msg')  
    def test_my_case(self, msg_mock):
      f_was_called = False

      async def f():
        global f_was_called   
        f_was_called = True

      self.service.callback_handler = MagicMock(wraps=f) # here I try to mock
      await self.service.handle(msg_mock)
      assert f_was_called is True

How can I patch already instantiated object method with some custom one? Is there some issues with corutines?

Upvotes: 2

Views: 1856

Answers (2)

Dan
Dan

Reputation: 1884

Try using a context manager by replacing this line:

self.service.callback_handler = MagicMock(wraps=f) # here I try to mock

With this:

with mock.patch.object(self.service, 'callback_handler', side_effect=f) as mock_cb:
    ... # rest of code indented

Upvotes: 2

etlsh
etlsh

Reputation: 701

I also faced the problem trying to mock asyncio and want into a lot of troubles,

I ended using pytest.asycio plugin .

@pytest.mark.asyncio
async def test_some_asyncio_code():
    res = await library.do_something()
    assert b'expected result' == res

Upvotes: 0

Related Questions