Django - 写作单元测试与模拟

时间:2017-01-10 15:58:41

标签: python django unit-testing

我最近开始研究Django项目。首先,我阅读book on TDD with Python和官方文档(tests)。还有一些博客。

我注意到的一件事是,他们编写了访问数据库模型的测试。请考虑here

中的以下代码段
def test_home_page_can_save_a_POST_request(self):
    request = HttpRequest()
    request.method = 'POST'
    request.POST['item_text'] = 'A new list item'

    response = home_page(request)

    self.assertEqual(Item.objects.count(), 1)
    new_item = Item.objects.first()
    self.assertEqual(new_item.text, 'A new list item')

测试断言Item对象的数量是否为1.因此测试实际上是从数据库中添加和检索数据。不会让测试变慢吗?

如果测试是并行化的,如果有另一个添加Item对象的测试,这个测试用例可能会失败,对吗?

修补方法/对象怎么样?上面的代码片段可以像这样重构

@patch('my_app.views.Item')
def test_home_page_can_save_a_POST_request(self, mock_item):
    request = HttpRequest()
    request.method = POST
    request.POST['item_text'] = 'A new list item'

    response = home_page(request)

    self.assertTrue(mock_item.objects.create.called)

我是Django的新手,我不熟悉这些做法。我访问过的教程编写了与数据库对话的测试。我想知道,这是否是Django项目测试的惯例。 Django生态系统中第二个片段(使用补丁和模拟)是否完美无缺?

修改:与表单相同 - 模拟form.is_valid方法返回TrueFalse,前提是表单有单独的单元测试。

P.S。使用Python的TDD是一本很棒的书,它帮助我在入职方面取得了很大的进步。我肯定会向任何学习Django的人推荐。

1 个答案:

答案 0 :(得分:1)

如果你想测试你的模型,你很难绕过数据库,是的,它确实可以使测试有点慢,即使使用内存中的SQLite数据库 - 这可能导致其他问题FWIW,因为SQLite不是像PostgreSQL这样的透明替代品。

但假设您在视图中调用的任何模型或其他函数/对象/方法都有自己的单元测试,并且您只想检查您的视图执行预期的调用,模拟是可行的策略 - 实际上可能比测试结果更安全预期的调用(主要是将您的单元测试转换为集成测试)。