-
Notifications
You must be signed in to change notification settings - Fork 381
unittesting_async
Carter Tinney edited this page Sep 9, 2019
·
1 revision
Our tooling is currently flawed for testing coroutine functions, as coroutine functions return asyncio.Future
objects rather than the result of the call. This makes mocking tricky, even when using both the pytest-mock and pytest-asyncio extensions.
In order to mock a coroutine function/method to A) return a value, and B) not hang forever, do something like the following:
async def create_completed_future(result=None):
f = asyncio.Future()
f.set_result(result)
return f
@pytest.mark.describe("Foo - Bar")
class TestBar(object):
@pytest.mark.it("Returns 'buzz' when called")
async def test_returns_buzz(self, mocker):
foo = FooClient()
mocker.patch(foo, "bar", return_value=(await create_completed_future("buzz")))
res = await foo.bar()
assert res == "buzz"
As you can see, by returning a completed future the mocked coroutine method was able to be compatible with the await
syntax. Additionally, the result of the future was set to the mocked return value, which was then transferred to the variable res
after the await
was resolved.