6

我想模拟以下CanonPerson模型

def compute(self, is_send_emails, test_email_address):
        cpses = CanonPerson.objects.filter(persons__vpd=6,
                                           persons__country="United States",
                                           persons__role__icontains=';IX;').prefetch_related("persons").using("global")

        for cp in cpses:
           ...

我很迷茫如何模拟CanonPerson.objects.filter给我一个可交互的集合,以便我可以继续。

这是我到目前为止所做的:

def test_X_count(self):
    with mock.patch('apps.dbank.models.CanonPerson.objects.filter') as canon_patch:
        mock_cp = mock.MagicMock(spec=CanonPerson)
        mock_person = mock.MagicMock(spec=Person)
        mock_person.vpd = 6
        mock_cp.country = "United States"
        mock_cp.role = ";IX;"
        mock_cp.persons.add(mock_person)
        canon_patch.objects.filter.return_value = [mock_cp] // ???
        oi = OptinInvites()
        oi.compute(False, None)
        oi.get_most_recent_email.assert_called_once_with(1)

在计算函数中我可以看到cpses是一个 MagicMock 类型。然而,它是不可迭代的for loop,之后,只是跳过它。我想通过将返回值设置为[mock_cp]我会创建一个可迭代的列表?

4

1 回答 1

8

您为其分配返回值的行canon_patch略有错误。你在哪里:

canon_patch.objects.filter.return_value = [mock_cp]

它应该是:

canon_patch.return_value = [mock_cp]

canon_patch已经是“objects.filter”的模拟了。

[mock_cp]如果您打电话,您的原始线路将返回CanonPerson.objects.filter.objects.filter()

如果你真的想修补CanonPerson模型,那么你的修补线看起来像:

with mock.patch('apps.dbank.models.CanonPerson') as canon_patch:

您可能还会发现您需要在使用它的位置模拟它,而不是从您导入它的位置。因此,假设您在测试中使用CanonPerson了一个名为my_module您的补丁代码的模块,可能如下所示:

with mock.patch('my_module.CanonPerson') as canon_patch:
于 2014-10-24T12:09:52.013 回答