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

Python异步测试中assert_awaited_once_with断言失效问题排查

问题原因及解决方案

1. 断言写法错误导致直接报错

你测试代码里的assert mock_bulk_create.assert_awaited_once_with(items)是错误写法。assert_awaited_once_with这类Mock断言方法本身会在条件不满足时抛出AssertionError,并且执行成功后返回None。用assert包裹它相当于断言None为真,这必然触发报错。

2. Mock对象的目标错误

你当前patch的是QuerySet类的abulk_create方法,但实际代码中调用的是models.Temperature.objects.abulk_create(items)。objects是Temperature模型的Manager实例,虽然Manager的部分方法会委托给QuerySet,但直接patch QuerySet类的方法,无法正确拦截Manager实例上的异步方法调用(受Django异步方法的实现细节影响)。


修复后的测试代码

import datetime

from unittest.mock import patch, AsyncMock
from django.test import TestCase

class TestTemperatureQueue(TestCase):
    @patch('temperature.models.Temperature.objects.abulk_create')
    async def test_add_ten(self, mock_bulk_create: AsyncMock):
        from temperature import models
        from temperature.management.commands import ingest_temps
        
        # 创建测试用的Temperature实例
        items = [
            models.Temperature(
                value=i, 
                timestamp=datetime.datetime.now(tz=datetime.timezone.utc)
            ) for i in range(10)
        ]
        
        queue = ingest_temps.TemperatureQueue([])
        for i, item in enumerate(items):
            await queue.add(item)
            if i < 9:
                assert len(queue) == i + 1
                assert queue == items[:i+1]
                continue
            assert len(queue) == 0
        
        # 直接调用断言方法,无需用assert包裹
        mock_bulk_create.assert_awaited_once_with(items)

关键修复点

  • 移除多余的assert包裹:直接调用mock_bulk_create.assert_awaited_once_with(items),该方法会自行验证调用情况,不满足时抛出断言错误。
  • 修正patch目标:改为直接patchtemperature.models.Temperature.objects.abulk_create(替换为你项目中实际的模型路径),确保拦截到代码中实际调用的方法。

内容的提问来源于stack exchange,提问作者spacether

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:57:25