首页 > 解决方案 > 在 Django 测试中匹配查询集

问题描述

我有一个 Django 应用程序,在我的测试中我运行这个代码:

def test_search_keywords_logic(self):
    response = self.client.get(reverse('search-results'), { 'q': 'test11' })
    nt.assert_equal(response.status_code, 200)
    nt.assert_equal(response.context['query_string'], 'test11')
    nt.assert_equal(response.context['total_results'], 1)
    nt.assert_equal(response.context['found_results'], True)
    qs = QuerySet(CaseStudy.objects.filter(title='test1'))
    nt.assert_queryset_equal(response.context['study_results'], qs)

最后一行:nt.assert_queryset_equal(response.context['study_results'], qs) 给我错误:AttributeError: 'QuerySet' object has no attribute '_meta'

我不确定这意味着什么。我要做的就是断言上下文变量“study_results”中返回的查询集与我知道CaseStudy.objects.get(title='test1')的应该返回正确的 CaseStudy 对象相匹配,因为它是测试数据库中唯一的一个。但是,它似乎不起作用。我还尝试将响应上下文 'study_results' 与 'study_results' 进行比较<CaseStudy: test1>,甚至尝试将其包装在QuerySet(). 它仍然不起作用,似乎将我QuerySet()的 for test1 视为 test1 字符串分为单个字符的列表。

我试过两者都用nt.assert_equal()nt.assert_queryset_equal() 也不管用。

让这些断言通过的正确/有效方法是什么?我知道 study_results 上下文在这种情况下返回 CaseStudy: test1 。我似乎无法让它在断言中匹配。因为我从objects.filter它已经是一个查询集得到它,但即使.get()我无法让它工作。

我的问题似乎在比较的右侧,即使我只是输入'test1or<CaseStudy: test1>QuerySet('test1')它不起作用。

任何帮助,将不胜感激。

编辑:

使用此代码遇到此错误:

    qs = CaseStudy.objects.filter(title='test1')
    nt.assert_queryset_equal(response.context['study_results'], qs)

错误:

FAIL: test_search_keywords_logic (sasite.tests.tests.TestSearch)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/app/sasite/tests/tests.py", line 62, in test_search_keywords_logic
    nt.assert_queryset_equal(response.context['study_results'], qs)
  File "/usr/local/lib/python3.6/site-packages/django/test/testcases.py", line 972, in assertQuerysetEqual
    return self.assertEqual(list(items), values, msg=msg)
AssertionError: Lists differ: ['test1'] != [test1]
First differing element 0:
'test1'
test1
- ['test1']
?  -     -
+ [test1]

编辑2:

相关搜索结果查看代码:

keywords_dicts_study = CaseStudy.objects.all().values('pk', 'keywords', 'category')
match_set_study = set()
target = []
for kd in keywords_dicts_study:
    keywords = kd['keywords'].split(',')
    for word in keywords:
        target.append(word)
    target.append(kd['category'])

    for query in normalize_query(query_string):
        for x in target:
            if query.lower().strip(',').strip() == x.lower().strip():
                match_set_study.add(kd['pk'])

编辑3:

我将代码更改为:

qs = CaseStudy.objects.filter(title='test1')
nt.assert_equal(response.context['study_results'], [qs])

现在得到这个错误:

Traceback (most recent call last):
  File "/app/sasite/tests/tests.py", line 62, in test_search_keywords_logic
    nt.assert_queryset_equal(response.context['study_results'], [qs])
  File "/usr/local/lib/python3.6/site-packages/django/test/testcases.py", line 972, in assertQuerysetEqual
    return self.assertEqual(list(items), values, msg=msg)
AssertionError: Lists differ: ['test1'] != [<QuerySet [test1]>]
First differing element 0:
'test1'
<QuerySet [test1]>
- ['test1']
+ [<QuerySet [test1]>]

所以它现在将 my[qs]视为一个 QuerySet。但它似乎不是response.context['page_results']QuerySet 本身。我不应该在这里使用nt.assert_queryset_equal()吗?而只是使用nt.assert_equal()

究竟是什么response.context['page_results']?它本身是一个 QuerySet 吗?因为好像不是这样。它作为['test1']. 如果我更改[qs]为,qs那么我将获得'[test1]'该值。我似乎无法让它们正确对齐。

我的目标是nt.assert_queryset_equal()最终成为真正的使用response.contex['study_results']CaseStudy.objects.filter(title='test1')

有人可以建议一种方法来实现这一目标吗?

谢谢

标签: pythondjangodockertesting

解决方案


我不确定你为什么在那个查询上调用 QuerySet。filter()已经返回一个查询集;似乎没有任何理由将其包装在另一个中。你应该删除它。

qs = CaseStudy.objects.filter(title='test1')
nt.assert_queryset_equal(response.context['study_results'], qs)

推荐阅读