简体   繁体   中英

How to make unit test with `asyncio.sleep()` contained code?

I have a problem to write asyncio.sleep contained unit tests. Do I wait actual sleep time...?

I used freezegun to mocking time. This library is really helpful when I try to run tests with normal callables. but I cannot find answer to run tests which contains asyncio.sleep!

async def too_many_sleep(delay):
    await asyncio.sleep(delay)
    do_something()

def test_code():
    task = event_loop.create_task(too_many_sleep(10000))
    # I want test like `assert_called(do_something)` without realtime delays

What I want:

def test_code():
    task = event_loop.create_task(too_many_sleep(10000))

    ...
    # trick the time
    with time_shift(sec=10000):
        assert task.done()

What I'm doing:

def test_code():
    task = event_loop.create_task(too_many_sleep(10000))
    # run tests and I will see a sunrise

No, freezegun doesn't patch affect asyncio.sleep() , because freezegun doesn't patch the asyncio loop.time() method .

There is an existing issue in the freezegun project repository that asks how to deal with asyncio.sleep() , but it is still open with no proposed solution.

You could just mock asyncio.sleep() yourself:

from unittest import mock

class AsyncMock(mock.MagicMock):
    async def __call__(self, *args, **kwargs):
        return super(AsyncMock, self).__call__(*args, **kwargs)

with mock.patch('asyncio.sleep', new_callable=AsyncMock):
    task = event_loop.create_task(too_many_sleep(10000))

The above replaces asyncio.sleep with an AsyncMock() instance for the duration of the test, and AsyncMock() , when called, just does nothing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM