Skip to content

Commit

Permalink
Merge pull request #179 from frankie567/issue-178
Browse files Browse the repository at this point in the history
Fix #178: handle spy on async functions
  • Loading branch information
nicoddemus committed Jan 28, 2020
2 parents 2abec3b + f8f87fd commit 97f897f
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 5 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Expand Up @@ -56,11 +56,12 @@ jobs:
deploy:

if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')

runs-on: ubuntu-latest

needs: [build, linting]


steps:
- uses: actions/checkout@v1
- name: Set up Python
Expand All @@ -75,7 +76,6 @@ jobs:
run: |
python setup.py sdist bdist_wheel
- name: Publish package to PyPI
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.rst
@@ -1,3 +1,14 @@
3.0.0 (UNRELEASED)
------------------

* Python 2.7 and 3.4 are no longer supported. Users using ``pip 9`` or later will install
a compatible version automatically.

* ``mocker.spy`` now also works with ``async def`` functions (`#179`_). Thanks `@frankie567`_ for the PR!

.. _#179: https://github.com/pytest-dev/pytest-mock/issues/179
.. _@frankie567: https://github.com/frankie567

2.0.0 (2020-01-04)
------------------

Expand Down
2 changes: 2 additions & 0 deletions README.rst
Expand Up @@ -114,6 +114,8 @@ In addition, spy objects contain two extra attributes:

``mocker.spy`` also works for class and static methods.

As of version 3.0.0, ``mocker.spy`` also works with ``async def`` functions.

.. note::

In versions earlier than ``2.0``, the attributes were called ``return_value`` and
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -19,7 +19,7 @@
description="Thin-wrapper around the mock package for easier use with pytest",
long_description=open("README.rst", encoding="utf-8").read(),
keywords="pytest mock",
extras_require={"dev": ["pre-commit", "tox"]},
extras_require={"dev": ["pre-commit", "tox", "pytest-asyncio"]},
classifiers=[
"Development Status :: 5 - Production/Stable",
"Framework :: Pytest",
Expand Down
21 changes: 19 additions & 2 deletions src/pytest_mock/plugin.py
@@ -1,3 +1,4 @@
import asyncio
import functools
import inspect

Expand Down Expand Up @@ -96,7 +97,6 @@ def spy(self, obj, name):
if isinstance(value, (classmethod, staticmethod)):
autospec = False

@functools.wraps(method)
def wrapper(*args, **kwargs):
spy_obj.spy_return = None
spy_obj.spy_exception = None
Expand All @@ -109,7 +109,24 @@ def wrapper(*args, **kwargs):
spy_obj.spy_return = r
return r

spy_obj = self.patch.object(obj, name, side_effect=wrapper, autospec=autospec)
async def async_wrapper(*args, **kwargs):
spy_obj.spy_return = None
spy_obj.spy_exception = None
try:
r = await method(*args, **kwargs)
except Exception as e:
spy_obj.spy_exception = e
raise
else:
spy_obj.spy_return = r
return r

if asyncio.iscoroutinefunction(method):
wrapped = functools.update_wrapper(async_wrapper, method)
else:
wrapped = functools.update_wrapper(wrapper, method)

spy_obj = self.patch.object(obj, name, side_effect=wrapped, autospec=autospec)
spy_obj.spy_return = None
spy_obj.spy_exception = None
return spy_obj
Expand Down
15 changes: 15 additions & 0 deletions tests/test_pytest_mock.py
Expand Up @@ -405,6 +405,21 @@ def __call__(self, x):
assert spy.spy_return == 20


@pytest.mark.asyncio
async def test_instance_async_method_spy(mocker):
class Foo:
async def bar(self, arg):
return arg * 2

foo = Foo()
spy = mocker.spy(foo, "bar")

result = await foo.bar(10)

spy.assert_called_once_with(10)
assert result == 20


@contextmanager
def assert_traceback():
"""
Expand Down
1 change: 1 addition & 0 deletions tox.ini
Expand Up @@ -5,6 +5,7 @@ envlist = py{35,36,37,38}, linting, norewrite
passenv = USER USERNAME
deps =
coverage
pytest-asyncio
commands =
coverage run --append --source={envsitepackagesdir}/pytest_mock -m pytest tests

Expand Down

0 comments on commit 97f897f

Please sign in to comment.