You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单元测试中仅Mock被测代码的asyncio.sleep以加速测试?

解决仅Patch被测代码中asyncio.sleep的问题

问题根源:Python的标准库模块(比如asyncio)是单例模式,被测代码sut.py和测试代码test.py导入的是同一个asyncio对象。因此直接patch sut.asyncio.sleep会修改全局的asyncio.sleep,导致测试代码里的sleep也变成Mock实例,无法在测试逻辑中使用原生sleep实现快速延迟。

方案1:封装被测代码中的sleep(推荐)

在被测代码中封装独立的sleep函数,业务逻辑调用这个封装函数,测试时仅patch该封装函数,不会影响全局asyncio.sleep。

修改sut.py:

import asyncio

# 封装sleep供业务代码调用
async def sleep(delay):
    await asyncio.sleep(delay)

async def target_func():
    # 业务逻辑中使用封装的sleep
    await sleep(10)
    # 其他业务代码...

测试代码test.py:

import asyncio
import pytest
from unittest.mock import patch
import sut

@pytest.mark.asyncio
@patch("sut.sleep")
async def test_fast_sleep(mock_sleep):
    # 定义快速sleep逻辑,使用原生asyncio.sleep
    async def fast_sleep(t):
        await asyncio.sleep(t / 10)
    mock_sleep.side_effect = fast_sleep

    # 执行被测函数
    await sut.target_func()

    # 验证sleep调用参数
    mock_sleep.assert_called_once_with(10)

方案2:不修改被测代码,保存原生sleep后全局Patch

如果无法改动被测代码,可在Patch前保存原生的asyncio.sleep,在side_effect中调用原生函数实现缩短延迟:

import asyncio
import pytest
from unittest.mock import patch
import sut

# 提前保存原生sleep函数
original_sleep = asyncio.sleep

@pytest.mark.asyncio
@patch("asyncio.sleep")
async def test_fast_sleep_global(mock_sleep):
    async def fast_sleep(t):
        # 调用原生sleep,传入1/10的延迟
        await original_sleep(t / 10)
    mock_sleep.side_effect = fast_sleep

    # 执行被测函数
    await sut.target_func()

    # 验证调用断言
    mock_sleep.assert_called_once_with(10)

注意:该方案会全局替换asyncio.sleep,测试代码中如果自行调用asyncio.sleep也会使用快速版本,需根据测试场景判断是否适用。

内容的提问来源于stack exchange,提问作者Joe C.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 13:55:10