Django中的TDD,如何对模型进行单元测试?

时间:2018-08-09 09:14:21

标签: django tdd

我是TDD的新手,并试图在Django项目中应用TDD练习。

基于伦敦学校的TDD工作流程,我正在由内而外地工作,即视图层,表单层和模型层。在表单层,我计划构建一个模型表单,其中包含一些 自定义验证方法。我认为,基于TDD,我只需要测试我的自定义方法, 无需触摸:

  • Django提供的整个ModelForm逻辑,这是一个经过充分测试的依赖项。
  • 较低的模型层,尚不存在。

但是我该怎么办呢?例如,使用以下模型形式:

from django import forms
from app import models

class MyModelForm(forms.ModelForm):

    class Meta:
        model = models.MyModel
        fields = ("field1", "field2")

    def clean_field1(self):
        # custom cleaning logic

    def clean_field2(self):
        # custom cleaning logic

    def clean(self):
        # custom cleaning logic
  • 我如何(或应该)模拟MyModel?我想出了

    @patch("app.forms.MyModelForm._meta.model")
    class FormTest(TestCase):
        #...
    

    但是也许有点疯狂?而且我不确定Mock有多好 对象将使用ModelForm内部逻辑。一方面,所有形式 字段不见了,不是吗?

  • 如何对这些自定义方法进行单元测试?通过手动设置self.cleaned_data

1 个答案:

答案 0 :(得分:1)

使用django之类的框架时,编写单元测试很棘手。问题在于,Django设计将模型和表单紧密地结合在一起。通过这里的耦合,我的意思是例如表单期望模型中存在特定字段。

鉴于模型本身很少具有任何逻辑,并且通常仅是字段的定义,我想说,与模型一起测试表单而不模拟它更实用。在大多数情况下,您在表单中定义的逻辑测试将仅取决于字段的定义。

但是回到您的问题上。

您可以成为纯粹主义者并嘲弄模型。为了隔离测试表单,您需要模拟模型,但要有所不同。代替使用纯Mock,您需要使用此表单可以使用的模型的最小定义来创建另一个测试模型。该测试模型在表格和模型之间建立一种契约。即该表格期望模型具有的字段。然后在测试中,应使用测试模型来模拟表单中的模型。

您可以使用常规的TDD增量步骤练习来做到这一点。这是从表单开始,对一个字段进行测试,然后创建(最初为空)测试模型,并在表单中为它们进行创建测试的同时向其中一个字段添加一个字段。

当然,您仍然需要集成测试(或多个测试)来检查您的表单是否适用于实际模型。

这是重要的一点。正确的是,您不应该测试django提供的逻辑。但这并不意味着您的测试不能依赖它并使用它。

这同样适用于您自己的代码。表单测试不应直接测试您的模型,但从实际角度来看,它可以依赖真实模型(假设模型逻辑本身也已在其自己的测试中进行了测试)。有人会说这不是纯粹的单元测试,而是您使用the Web framework for perfectionists with deadlines所要付出的代价。