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目标:改为直接patch
temperature.models.Temperature.objects.abulk_create(替换为你项目中实际的模型路径),确保拦截到代码中实际调用的方法。
内容的提问来源于stack exchange,提问作者spacether
相关产品推荐
相关产品推荐

