Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stub.assert_called_once_with has distracting reporting #26

Closed
Chronial opened this issue Jan 26, 2016 · 4 comments
Closed

stub.assert_called_once_with has distracting reporting #26

Chronial opened this issue Jan 26, 2016 · 4 comments

Comments

@Chronial
Copy link
Contributor

assert_called_once_with and the other assert_ functions show in the traceback, which is very unhelpful. __tracebackhide__ would help, but this is is a system lib :).

Test

def test_stub(mocker):
    stub = mocker.stub()
    stub.assert_called_once_with('foo', 'baz')

Output:

================================================================================== FAILURES ==================================================================================
_________________________________________________________________________________ test_stub __________________________________________________________________________________

mocker = <pytest_mock.MockFixture object at 0x7f52cb320cc0>

    def test_stub(mocker):
        stub = mocker.stub()
>       stub.assert_called_once_with('foo', 'baz')

mocker     = <pytest_mock.MockFixture object at 0x7f52cb320cc0>
stub       = <MagicMock spec='function' id='139993573101520'>

tests/ston/test_utils.py:21:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

_mock_self = <MagicMock spec='function' id='139993573101520'>, args = ('foo', 'baz'), kwargs = {}, self = <MagicMock spec='function' id='139993573101520'>
msg = "Expected 'mock' to be called once. Called 0 times."

    def assert_called_once_with(_mock_self, *args, **kwargs):
        """assert that the mock was called exactly once and with the specified
            arguments."""
        self = _mock_self
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times." %
                   (self._mock_name or 'mock', self.call_count))
>           raise AssertionError(msg)
E           AssertionError: Expected 'mock' to be called once. Called 0 times.

_mock_self = <MagicMock spec='function' id='139993573101520'>
args       = ('foo', 'baz')
kwargs     = {}
msg        = "Expected 'mock' to be called once. Called 0 times."
self       = <MagicMock spec='function' id='139993573101520'>

/usr/lib/python3.4/unittest/mock.py:781: AssertionError

Expected Output:

================================================================================== FAILURES ==================================================================================
_________________________________________________________________________________ test_stub __________________________________________________________________________________

mocker = <pytest_mock.MockFixture object at 0x7f07b55ed128>

    def test_stub(mocker):
        stub = mocker.stub()
>       stub.assert_called_once_with('foo', 'baz')
E       AssertionError: Expected 'mock' to be called once. Called 0 times.

mocker     = <pytest_mock.MockFixture object at 0x7f07b55ed128>
stub       = <MagicMock spec='function' id='139671084389320'>

tests/ston/test_utils.py:21: AssertionError
@nicoddemus
Copy link
Member

Thanks for the report! I'm not sure how to tackle this without some ugly ugly hack, but I will see if I figure something out.

Thanks again!

@Chronial
Copy link
Contributor Author

How about this: Monkeypatch the five assert_ functions in the mock library (can't help but chuckle at the irony of this ^^) by wrapping them in a handler that has __tracebackhide__, catches all AssertionErrors and raises a new one with the same message.

This solution does not seem too ugly. And a lot less ugly than messing with tracebacks.

That leaves the question when to monkeypatch the functions – on pytest setup or only for the mocker fixture. I would do this on pytest setup, since people might use the mock library without requesting the mocker, and would still want this behavior. It also seems very unlikely that the wrapper could break anything – it keeps the exact same behaviour, not even introducing any sideeffects. Unless someone else is monkeypatching the mock library or messing with tracebacks.

What do you think?

@nicoddemus
Copy link
Member

Sounds good, I had a similar idea but didn't think of monkeypatching the entire mock module (only when using objects created by mocker, like mocker.patch).

@nicoddemus
Copy link
Member

Btw, a PR would be very welcome! 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants