Skip to content
This repository has been archived by the owner on Oct 11, 2023. It is now read-only.

unittesting_async

Carter Tinney edited this page May 22, 2019 · 1 revision

Testing with Async/Await

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.

Clone this wiki locally