首页 > 解决方案 > 如何使用 `asyncio.sleep()` 包含的代码进行单元测试?

问题描述

我在编写包含 asyncio.sleep 的单元测试时遇到问题。我要等待实际的睡眠时间吗...?

我曾经freezegun嘲笑过时间。当我尝试使用普通的可调用对象运行测试时,这个库真的很有帮助。但我找不到运行包含 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

我想要的是:

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

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

我在做什么:

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

标签: python

解决方案


不,freezegun不修补影响asyncio.sleep(),因为freezegun不修补asyncioloop.time()方法

项目存储库中存在一个询问如何处理的问题freezegunasyncio.sleep()但它仍然是开放的,没有建议的解决方案。

你可以嘲笑asyncio.sleep()自己:

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))

在测试期间,上面的内容替换asyncio.sleep为一个AsyncMock()实例,并且AsyncMock()在调用时,什么也不做。


推荐阅读