Message367913
MagicMock object on call returns another MagicMock. AsyncMock object in turn returns a coroutine which has to be awaited.
In the report mock.MagicMock().__aenter__() returns an AsyncMock object. Accessing the query attribute will create an AsyncMock object. Calling query() will return a coroutine which will not have a __aexit__. Mock supports configure_mock through which nested calls can be mocked but the return_value has to be accessed to mock the nested attributes. So a workaround could be below. The connection object is mocked such that the __aenter__ returns a MagicMock. That magic mock can have the query attribute to be mocked whose return_value is an AsyncMock if the the query object has to awaited.
See also issue37052 regarding adding an example. See also https://github.com/python/cpython/pull/16859 regarding adding an example along similar database mocking that will help.
>>> from unittest.mock import MagicMock, AsyncMock
<MagicMock name='mock()' id='140285187747744'>
>>> AsyncMock()()
<coroutine object AsyncMockMixin._mock_call at 0x7f96b0c5f3c0>
import asyncio
from unittest.mock import MagicMock, AsyncMock, patch
class Database:
pass
async def mock_database():
with patch(f"{__name__}.Database") as db:
db.configure_mock(
**{
"connection.return_value.__aenter__.return_value": MagicMock(
**{
"query.return_value.__aenter__.return_value": AsyncMock(
return_value=[1]
)
}
)
}
)
async with db.connection() as conn:
async with conn.query() as query:
result = await query("select * from people")
assert result == [1]
print(f"Result : {result}")
asyncio.run(mock_database())
Hope it helps. |
|
Date |
User |
Action |
Args |
2020-05-02 04:22:07 | xtreak | set | recipients:
+ xtreak, brian.curtin, asvetlov, yselivanov, graingert, lisroach |
2020-05-02 04:22:07 | xtreak | set | messageid: <1588393327.69.0.298278070027.issue40406@roundup.psfhosted.org> |
2020-05-02 04:22:07 | xtreak | link | issue40406 messages |
2020-05-02 04:22:07 | xtreak | create | |
|