You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
With the growing use of asyncio, we need ways to mock Coroutines.
Currently, mock and unittest.mock do not support creating specs for coroutines (AsyncMock is being added in python 3.8).
As a work around, we're using asynctest.mock, which has the same interface as unittest.mock, however this requires us to completely re-implement the __init__ method of MockFixture, and removes the "hide traceback" functionality (though we don't care too much about this).
This allows us to have both mocker and async_mocker fixtures.
TLDR
To ease this usecase (and potentially others), Can support for defining a mock modules path from the config be added please?
Please note: asynctest.mock.CoroutineMock is not compatible with unittest.mock.AsyncMock.
It is not a drop-in replacement.
Moreover, AsyncMock doesn't exist on it's own, it is deeply integrated with other unittest.mock objects and functions. Thus, the whole unittest.mock should be replaced with asynctest.mock with even more incompatibility level.
I rather suggest not touching pytest-mock library but wait for 3.8.
Similar but slightly different API makes more harm than help.
The support of such solutions is hard in long term perspective.
If you really need asynctest.mock.CoroutineMock support you can clone pytest-mock, add needed hacks, and use it on your own.
I didn't take a look at the problem in detail, but @asvetlov makes a point about supporting slightly different APIs in the same package brings more problems than it helps.
Perhaps we should create a new pytest-asyncmock plugin instead?
agree with your points on this.
I think it's probably best to wait until 3.8 for this library.
In terms of creating a new plugin, it might be better to try and get the fixtures into the asynctest library instead.
Will close this issue for now.
The hack we have in place works well enough for us until that time, and for our specific usecase, it will be an easy migration.
If anyone else stumbles on this issue, here is the hack:
importpytestimportpytest_mockimportasynctest.mock@pytest.fixturedefasync_mocker(pytestconfig):
# This is a straight copy + paste from pytest_mock, but with our patched MockFixtureresult=AsyncMockFixture(pytestconfig)
yieldresultresult.stopall()
classAsyncMockFixture(pytest_mock.MockFixture):
def__init__(self, config):
# This is a straight copy + paste from pytest_mock# TODO: contribute a way to use arbitary mock libraries upstreamself._patches= [] # list of mock._patch objectsself._mocks= [] # list of MagicMock objects# CHANGED: hard coding the asynctest.mockself.mock_module=mock_module=asynctest.mockself.patch=self._Patcher(self._patches, self._mocks, mock_module)
# aliases for convenienceself.Mock=mock_module.Mockself.MagicMock=mock_module.MagicMockself.NonCallableMock=mock_module.NonCallableMockself.PropertyMock=mock_module.PropertyMockself.call=mock_module.callself.ANY=mock_module.ANYself.DEFAULT=mock_module.DEFAULTself.create_autospec=mock_module.create_autospecself.sentinel=mock_module.sentinelself.mock_open=mock_module.mock_open# CoroutineMock is from asynctest# AsyncMock is being added in python 3.8# Please use AsyncMock.self.CoroutineMock=self.AsyncMock=mock_module.CoroutineMock
Reacted by Bruno Oliveira, Thomas LÉVEIL, Liam Diprose and Tuukka Mustonen
Will gladly accept PRs in this regard if all it is required is to provide a custom mock implementation, but I probably would not like to include it into pytest-mock it this would require an entire new implementation of pytest_mock.MockFixture.
Activity
asvetlov commentedon Jun 27, 2019
Please note:
asynctest.mock.CoroutineMockis not compatible withunittest.mock.AsyncMock.It is not a drop-in replacement.
Moreover,
AsyncMockdoesn't exist on it's own, it is deeply integrated with otherunittest.mockobjects and functions. Thus, the wholeunittest.mockshould be replaced withasynctest.mockwith even more incompatibility level.I rather suggest not touching
pytest-mocklibrary but wait for 3.8.Similar but slightly different API makes more harm than help.
The support of such solutions is hard in long term perspective.
If you really need
asynctest.mock.CoroutineMocksupport you can clonepytest-mock, add needed hacks, and use it on your own.nicoddemus commentedon Jun 27, 2019
I didn't take a look at the problem in detail, but @asvetlov makes a point about supporting slightly different APIs in the same package brings more problems than it helps.
Perhaps we should create a new
pytest-asyncmockplugin instead?antdking commentedon Jun 28, 2019
agree with your points on this.
I think it's probably best to wait until 3.8 for this library.
In terms of creating a new plugin, it might be better to try and get the fixtures into the
asynctestlibrary instead.Will close this issue for now.
The hack we have in place works well enough for us until that time, and for our specific usecase, it will be an easy migration.
If anyone else stumbles on this issue, here is the hack:
Jackenmen commentedon Oct 24, 2019
Python 3.8 is out. It might be worth reopening this issue as there's AsyncMock available now.
nicoddemus commentedon Oct 24, 2019
Thanks for the ping @jack1142.
Will gladly accept PRs in this regard if all it is required is to provide a custom mock implementation, but I probably would not like to include it into
pytest-mockit this would require an entire new implementation ofpytest_mock.MockFixture.ThibaultLemaire commentedon May 15, 2020
mocksince version 4.0.0 has theAsyncMockclass which could be exposed directly throughmocker.AsyncMock(like the usualmocker.Mock)EDIT: Sorry I thought
pytest-mockhad a dependency onmock, but this is not the case so it's not as easy as I thought.tirkarthi commentedon Jul 26, 2020
FWIW,
AsyncMockis now available as part of mocker from 449d3d0 with rich assert diff for assert helpers associated withAsyncMock