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

Python unittest:如何在测试方法内设置mock的side_effect返回不同值

解决方法:在测试方法内部设置mock的side_effect

我来帮你搞定这个问题!你之前的代码之所以没得到预期的Order实例,是因为把side_effect的位置放错了——你给mock_qs.return_value的MagicMock设置了side_effect,但实际上被patch的filter方法本身才是需要设置side_effect的对象。

正确的测试代码写法

from unittest import mock, TestCase
from your_app.models import Order  # 替换成你的Order模型实际路径

def method_to_test(): 
    qs1 = Order.objects.filter() 
    qs2 = Order.objects.filter() 
    return qs1, qs2  # 方便测试验证返回结果

class TestOrderFilterMethod(TestCase):
    @mock.patch('your_app.models.Order.objects.filter')  # 注意patch路径要与实际调用路径匹配
    def test_method_to_test(self, mock_filter): 
        # 直接在测试方法内部给被patch的filter方法设置side_effect
        mock_filter.side_effect = [Order(id=1), Order(id=2)]
        
        # 调用待测试方法
        result1, result2 = method_to_test()
        
        # 验证结果符合预期
        self.assertEqual(result1.id, 1)
        self.assertEqual(result2.id, 2)
        # 额外验证filter方法被调用了两次
        self.assertEqual(mock_filter.call_count, 2)

关键说明

  1. 理清mock对象层级:mock_filter就是被patch后的Order.objects.filter方法本身,当你调用Order.objects.filter()时,本质是调用这个mock对象。所以直接给它设置side_effect属性,就能让每次调用返回不同的值。
  2. side_effect的作用:当给mock对象设置side_effect为一个列表时,每次调用mock对象会依次返回列表中的元素,正好满足你两次查询返回不同结果的需求。
  3. 无需装饰器提前配置:完全不需要在@mock.patch里指定side_effect参数,在测试方法内部拿到mock参数后直接赋值即可,完美符合你的需求。

如果你的场景中filter应该返回QuerySet而不是单个实例,只需要把side_effect的元素改成QuerySet格式就行,比如:

mock_filter.side_effect = [
    Order.objects.filter(id=1),  # 可根据实际情况用真实QuerySet或模拟的QuerySet
    Order.objects.filter(id=2)
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:12:28