How to test if instance's method is called with "self" when mocking?

Viewed 1184

I'm using unittest.mock, this wonderful library. However I was surprised by an unexpected behavior, and I don't see an obvious solution. I'm using it for my unit tests and it is vital to understand perfectly how it behaves to have useful tests.

I know the code below in show_bar is broken, it is calling a classmethod instead of the instance method. However, all my mock unittests are passing :

Code containing a bug:

class Foo(object):
    def bar(self):
        return "bar"

    def show_bar(self):
        return Foo.bar()

Expected usage:

foo = Foo()
assert foo.show_bar() == "bar"
# => throw exception: bar() missing 1 required positional argument: 'self'

Unittest tries unsuccessfully to catch this error with mock:

from unittest.mock import patch
with patch.object(Foo, 'bar', return_value="bar") as mock:
    foo = Foo()
    assert foo.show_bar() == "bar"
mock.assert_called_once()
# => no errors 

Ideally, I would like to assert that bar is called with self.bar() and NOT Foo.bar() ; which is wrong. Unfortunately, using mock.assert_called_with() does not take in account the self nor cls parameter, so I'm a bit confused.

EDIT: Trying to clarify. I'm looking for best practices to use the library unittest.mock when we need to patch an object's method. It seems not clear to me how to patch it, currently I have no way to assert if it's calling self.bar or Foo.bar.

1 Answers
Related