-
Notifications
You must be signed in to change notification settings - Fork 313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prefer AsyncMock to as_future #1366
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! I noticed that there are still places where we use as_future
and I assume it's because the mock.patch
annotation uses regular mocks? In any case I think we should add pydocs with guidance when to use as_future
and state explicitly that mock.AsyncMock
is preferred. Also, can you please add a description in the PR body documenting the motivation for this PR?
@danielmitterdorfer I ended up completely removing |
Thanks! As there is now only one approach to test async code there's no need for any guidance anymore. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice cleanup! LGTM
In Python, calling an async function
f()
can be done in two steps:f()
await
the result, possibly laterThe driver tests took advantage of this detail to make
MagicMock
work with async functions by usingas_future
. With that trick, mocked functions return an awaitable result, which are then awaited in the tested code.However, coroutines are best thought as an implementation detail, and it's better to always call an async function
f
usingawait f()
, never separating the two steps mentioned above. Thankfully, Python 3.8 introducedAsyncMock
that allows removingas_future
by just specifying a return value, which avoids thinking about coroutines, which is what we want.There's just one wrinkle: while
mock.patch()
replaces the target with anAsyncMock
, it does not work recursively. So while we would like to rewriteto
we need to use
which is still an improvement as it avoids the
as_future
code smell.