如何测试是否调用了Django QuerySet方法?

时间:2019-03-29 11:56:15

标签: python django django-queryset python-unittest

说我有以下内容:

models.py

class FooQuerySet(models.QuerySet):

    def bar(self):
        return self.filter(...)


class Foo(models.Model):
    ...

    objects = models.Manager.from_queryset(FooQuerySet)

views.py

class FooListView(ListView):
    model = Foo

    def get_queryset(self):
        qs = super().get_queryset()

        return qs.bar()

我想测试调用视图时是否调用models.FooQuerySet.bar

到目前为止,我有:

request = RequestFactory().get('')
view = FooListView.as_view()

with mock.patch('<best_guess>') as mocked:
    mocked.return_value = Foo.objects.none()
    view(request)
    mocked.assert_called_once()

<best_guess>所在的位置:

  • foo_app.models.FooQuerySet.bar
  • foo_app.models.Foo.objects.bar
  • foo_app.views.Foo.objects.bar

没有一个有效。即使我偶然遇到了一个 did 有效的魔术补丁字符串,我还是担心我根本不明白这里发生了什么。测试FooQuerySet.bar()被调用的正确方法是什么?

(将QuerySet链接起来也增加了难度,所以我可能有一天需要知道是否调用了FooQuerySet.any().amount().of().weird().methods().bar())。

1 个答案:

答案 0 :(得分:0)

我会尝试模拟ListView.get_queryset并将其保留为MagicMock,例如:

with mock.patch("foo_app.views.ListView.get_queryset") as mocked:
    view(request)
    mocked.bar.assert_called_once()

然后对于一长串的回调,只需使用:

mocked.bar.return_value.any.return_value.amount.return_value.of.assert_called_once()
...

但是请记住,如果视图依赖于返回的QuerySet,则在显示MagicMock实例时,它可能会引发一些错误。