简体   繁体   中英

Python mock - Check if methods are called in mocked object

I have a certain piece of code that looks like this:

# file1.py
from module import Object

def method():
    o = Object("param1")
    o.do_something("param2")

I have unittests that look like this:

@patch("file1.Object")
class TestFile(unittest.TestCase):
    def test_call(self, obj):
        ...

I can do obj.assert_called_with() in the unittest to verify that the constructor was called with certain parameters. Is it possible to verify that obj.do_something was called with certain parameters? My instinct is no, as the Mock is fully encapsulated within Object, but I was hoping there might be some other way.

You can do this, because the arguments are passed to the mock object.
This should work:

@patch("file1.Object")
class TestFile:
    def test_call(self, obj):
        method()
        obj.assert_called_once_with("param1")
        obj.return_value.do_something.assert_called_once_with("param2")

obj.return_value is the Object instance (which is a MagickMock object with the Object spec), and do_something is another mock in that object that is called with the given parameter.

As long as you are just passing arguments to mock objects, the mock will record this and you can check it. What you don't have is any side effects from the real function calls - so if the original do_something would call another function, this cannot be checked.

When you mock an object, it will mock the methods inside the object aswell. Therefore you are able to see if obj.do_something has been called with certain parameters as obj.do_something.assert_called_with()

For more information regarding unittest mocking can be found at the python library wiki https://docs.python.org/3/library/unittest.mock.html

A perfect example of what you are asking exist within that wiki source:

>>> mock = Mock()
>>> mock.method(1, 2, 3, test='wow')
<Mock name='mock.method()' id='...'>
>>> mock.method.assert_called_with(1, 2, 3, test='wow')

https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.assert_called_with

Regards, I see that you placed the the patching on the object, try placing it on the function instead, like:

class TestFile(unittest.TestCase):
    @patch("file1.Object")
    def test_call(self, obj):
        ...

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