如何模拟查询集以在 python/Mock 中的 for 循环中使用

use*_*726 7 python django unit-testing mocking

我正在编写一些单元测试并想使用 Mock。

鉴于以下代码:

# the 'real' query set is a Django database model
# qs = SomeDjangoModel.objects.filter(name='some_name')
qs = mock.Mock()
qs.filter.return_value = qs
item = mock.Mock()
item.do_work.return_value = "Some text"
qs.iter.return_value = iter([item])
# below is the code I want to test..
qs = qs.filter(name='some name')
qs = qs.filter(valid_from__lte=Timezone.now())
for obj in qs:
    obj.do_work()
Run Code Online (Sandbox Code Playgroud)

跑步时,我得到

类型错误:“模拟”对象不可迭代

我试过打补丁

@mock.patch('__builtin__.iter')
Run Code Online (Sandbox Code Playgroud)

但我似乎无法让它发挥作用。我还没有成功弄清楚当查询集被 for 循环“使用”时真正发生了什么。

非常感谢帮助!

[在第一个解决方案建议之后编辑了进一步添加的示例代码]

Sim*_*ser 1

通常我将 QuerySet 模拟为一个列表,这看起来更容易。所以:

something.return_value = [item]
Run Code Online (Sandbox Code Playgroud)

wheresomething是计算 QuerySet 的函数或位置。举一个实际的例子:

MyModel.objects.filter.return_value = [item]
Run Code Online (Sandbox Code Playgroud)

仅当您不使用 QuerySet 特定特征时,这才有效。

  • 这是如何在多个步骤中链接例如“filter()”的。 (2认同)