首页 > 解决方案 > How do you unit test Django RawQuerySets

问题描述

I'm using raw() and annotate() on a Django query and need some way to test it.

Here's what my code looks like (this is simplified significantly)

query = """SELECT
           table1.id, table1.column1, table1.column2,
           table2.other_column1, table2.other_column2 
           FROM myapp_mymodel as table1 
           JOIN otherapp_othermodel as table2 ON table1.othermodel_id = table2.id"""

return MyModel.objects.annotate(
    other_column1=models.Value('other_column1', models.IntegerField()),
    other_column2=models.Value('other_column2', models.DateField())
).raw(query)

It's relatively straightforward to fill the database with sample data, but what's the best way to check that the data is returned by this code?

There are a lot of options when dealing with standard querysets that seem to go out the window when dealing with RawQuerySets.

标签: djangounit-testingdjango-querysetdjango-ormpython-unittest

解决方案


通常的方法是让测试建立一个相对较小的数据集,其中包含一些查询应该找到的东西,以及一些它不应该找到的东西。然后检查返回QuerySet并验证:

  1. 它包含预期数量的结果
  2. 返回的主键值集与您期望返回的值匹配
  3. 返回对象上的注释值是预期的。

因此,例如,您可能会执行以下操作:

def test_custom_query(self):
    # Put whatever code you need here to insert the test data
    results = run_your_query_here()
    self.assertEqual(results.count(), expected_number_of_results)
    self.assertEqual({obj.pk for obj in results}, set_of_expected_primary_keys)
    self.assertEqual(
        [obj.annotated_value for obj in results],
        list_of_expected_annotated_values
    )

推荐阅读