python / cpython

The Python programming language
https://www.python.org
Other
62.75k stars 30.07k forks source link

mock.patch with autospec does not consume self / cls argument #76273

Closed 651e1c70-eaae-4801-8025-e18992128b87 closed 1 year ago

651e1c70-eaae-4801-8025-e18992128b87 commented 6 years ago
BPO 32092
Nosy @cjw296, @voidspace, @phmc, @lisroach, @mariocj89, @bclau, @tirkarthi
PRs
  • python/cpython#4476
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields: ```python assignee = None closed_at = None created_at = labels = ['3.7', '3.8', 'type-bug', 'library', '3.9'] title = 'mock.patch with autospec does not consume self / cls argument' updated_at = user = 'https://github.com/bclau' ``` bugs.python.org fields: ```python activity = actor = 'pconnell' assignee = 'none' closed = False closed_date = None closer = None components = ['Library (Lib)'] creation = creator = 'cbelu' dependencies = [] files = [] hgrepos = [] issue_num = 32092 keywords = ['patch'] message_count = 2.0 messages = ['306559', '306560'] nosy_count = 7.0 nosy_names = ['cjw296', 'michael.foord', 'pconnell', 'lisroach', 'mariocj89', 'cbelu', 'xtreak'] pr_nums = ['4476'] priority = 'normal' resolution = None stage = 'patch review' status = 'open' superseder = None type = 'behavior' url = 'https://bugs.python.org/issue32092' versions = ['Python 3.7', 'Python 3.8', 'Python 3.9'] ```

    651e1c70-eaae-4801-8025-e18992128b87 commented 6 years ago

    Currently, the autospec=True argument can be passed to mock.patch, but when trying to make assertions on the call and its arguments, it can fail, as it expects an instance / class instance reference as the first argument (self / cls arguments are not consumed when autospec-ing).

    Steps to reproduce:

    >>> import mock
    >>> from mock.tests import testmock
    >>>
    >>> with mock.patch.object(testmock.Something, 'meth', autospec=True):
    ...     smth = testmock.Something()
    ...     smth.meth(mock.sentinel.a, mock.sentinel.b, mock.sentinel.c, mock.sentinel.d)
    ...     smth.meth.assert_called_once_with(mock.sentinel.a, mock.sentinel.b, mock.sentinel.c, mock.sentinel.d)
    ...
    <MagicMock name='meth()' id='139792133225424'>
    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
      File "/usr/local/lib/python2.7/dist-packages/mock/mock.py", line 318, in assert_called_once_with
        return mock.assert_called_once_with(*args, **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/mock/mock.py", line 948, in assert_called_once_with
        return self.assert_called_with(*args, **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/mock/mock.py", line 937, in assert_called_with
        six.raise_from(AssertionError(_error_message(cause)), cause)
      File "/usr/local/lib/python2.7/dist-packages/six.py", line 718, in raise_from
        raise value
    AssertionError: Expected call: meth(sentinel.a, sentinel.b, sentinel.c, sentinel.d)
    Actual call: meth(<mock.tests.testmock.Something object at 0x7f23e456dcd0>, sentinel.a, sentinel.b, sentinel.c, sentinel.d)

    Expected result: no AssertionError.

    651e1c70-eaae-4801-8025-e18992128b87 commented 6 years ago

    Currently, the autospec=True argument can be passed to mock.patch, but when trying to make assertions on the call and its arguments, it can fail, as it expects an instance / class instance reference as the first argument (self / cls arguments are not consumed when autospec-ing).

    Steps to reproduce:

    ubuntu@ubuntu:/opt/stack/cpython$ ./python
    Python 3.7.0a2+ (heads/mock-add-autospec:51a9270, Nov 20 2017, 06:48:44)
    [GCC 5.4.0 20160609] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from unittest import mock
    from unittest.test.testmock import testmock
    with mock.patch.object(testmock.Something, 'meth', autospec=True):
        smth = testmock.Something()
        smth.meth(mock.sentinel.a, mock.sentinel.b, mock.sentinel.c, mock.sentinel.d)
        smth.meth.assert_called_once_with(mock.sentinel.a, mock.sentinel.b, mock.sentinel.c, mock.sentinel.d)
    >>> >>> >>> ... ... ... ... <MagicMock name='meth()' id='140281858112024'>
    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
      File "/opt/stack/cpython/Lib/unittest/mock.py", line 196, in assert_called_once_with
        return mock.assert_called_once_with(*args, **kwargs)
      File "/opt/stack/cpython/Lib/unittest/mock.py", line 856, in assert_called_once_with
        return self.assert_called_with(*args, **kwargs)
      File "/opt/stack/cpython/Lib/unittest/mock.py", line 845, in assert_called_with
        raise AssertionError(_error_message()) from cause
    AssertionError: Expected call: meth(sentinel.a, sentinel.b, sentinel.c, sentinel.d)
    Actual call: meth(<unittest.test.testmock.testmock.Something object at 0x7f95ea529a80>, sentinel.a, sentinel.b, sentinel.c, sentinel.d)

    Expected result: no AssertionError.

    iritkatriel commented 1 year ago

    @bclau is this still relevant? The code changed quite a lot since 3.7.