简体   繁体   中英

Mock a method call from an object created inside a function (python)

class Foo:
       def do_work:
          client = Client()
          client.widgets(self.widget_id).parts().get()``

I have the above code. Client() class is defined in another package. I am trying to unit test it with mock as follows:

    magic_mock = MagicMock()
    api_client = Client()
    magic_mock.api_client.widgets().parts().get.return_value = self.generate_mock

Unfortunately, it doesn't seem to work. What is a better approach?

If your class is in mymodule.py :

# mymodule.py
from othermodule import Client

class Foo:
    def do_work():
        client = Client()
        return client.widgets(self.widget_id).parts().get()

Then your test module should be something like (implement that generate_mock instead of mocked_value ):

# test_mymodule.py
from unittest.mock import patch

import mymodule


@patch('mymodule.Client')
def test_client_widgets_parts_get_returned(mocked):
    mocked_value = "foo"
    mocked.return_value.widgets.return_value.parts.return_value.get.return_value = mocked_value
    returned = mymodule.Foo().do_work()
    assert returned == mocked_value

Or without changing your do_work :

@patch('mymodule.Client')
def test_client_widgets_parts_get_called(mocked):
    mymodule.Foo().do_work()
    mocked.return_value.widgets.return_value.parts.return_value.get.assert_called()

PS stacked decorators are added from the bottom:

@patch('mymodule.Other')
@patch('mymodule.Client')
def test_client_widgets_parts_get_called(mocked_client, mocked_other):

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM