【问题标题】:TDD in Django, how to unit test my modelform?Django中的TDD,如何对我的模型进行单元测试?
【发布时间】:2018-08-09 09:14:20
【问题描述】:

我是 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

【问题讨论】:

  • 为被测单元打补丁似乎是个坏主意。但是您能否更好地了解您要测试的行为
  • @jonrsharpe 您好,感谢您的帮助。你认为MyModel这里属于被测单元?不是低级依赖(意思是表单层依赖模型层)吗?

标签: django tdd


【解决方案1】:

当使用像 django 这样的框架时,编写单元测试很棘手。问题是模型和表单通过 django 设计非常紧密地耦合在一起。在这里耦合是指例如表单期望模型中存在特定字段。

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

但回到你的问题。

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

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

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

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

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

【讨论】:

  • 谢谢,我同意你关于模型形式测试可以依赖于测试模型的观点。我最终得到的是一种策略,当 TDD 模型表单时,我首先创建一个占位符模型供该模型表单使用。并且只为我的自定义验证方法编写测试。如果我的任何自定义验证方法需要 django 的 ModelForm 逻辑(例如 cleaned_data)应该提供的数据,我会在我的测试用例中手动提供它们。表单层完成后,我进入模型层并通过相同的 TDD 工作流程填写占位符模型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-09
  • 2018-02-25
  • 1970-01-01
  • 2017-08-11
  • 2013-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多