Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions Doc/library/unittest.mock-examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -743,25 +743,24 @@ exception is raised in the setUp then tearDown is not called.
Mocking Unbound Methods
~~~~~~~~~~~~~~~~~~~~~~~

Whilst writing tests today I needed to patch an *unbound method* (patching the
method on the class rather than on the instance). I needed self to be passed
in as the first argument because I want to make asserts about which objects
were calling this particular method. The issue is that you can't patch with a
mock for this, because if you replace an unbound method with a mock it doesn't
become a bound method when fetched from the instance, and so it doesn't get
self passed in. The workaround is to patch the unbound method with a real
function instead. The :func:`patch` decorator makes it so simple to
patch out methods with a mock that having to create a real function becomes a
nuisance.
Sometimes a test needs to patch an *unbound method*, which means patching the
method on the class rather than on the instance. In order to make assertions
about which objects were calling this particular method, you need to pass
``self`` as the first argument. The issue is that you can't patch with a mock for
this, because if you replace an unbound method with a mock it doesn't become
a bound method when fetched from the instance, and so it doesn't get ``self``
passed in. The workaround is to patch the unbound method with a real function
instead. The :func:`patch` decorator makes it so simple to patch out methods
with a mock that having to create a real function becomes a nuisance.

If you pass ``autospec=True`` to patch then it does the patching with a
*real* function object. This function object has the same signature as the one
it is replacing, but delegates to a mock under the hood. You still get your
mock auto-created in exactly the same way as before. What it means though, is
that if you use it to patch out an unbound method on a class the mocked
function will be turned into a bound method if it is fetched from an instance.
It will have ``self`` passed in as the first argument, which is exactly what I
wanted:
It will have ``self`` passed in as the first argument, which is exactly what
was needed:

>>> class Foo:
... def foo(self):
Expand Down
Loading