对Django ModelFormset的验证/清除部分进行单元测试的最佳方法是什么?我的formset有一个干净的方法,根据其表单的值进行一些验证,我想对它进行单元测试。通用代码如下所示:
class AForm(ModelForm):
a = ChoiceField(choices=CHOICES)
b = FloatField()
def __init__(self, *args, **kwargs):
super(AForm, self).__init__(*args, **kwargs)
class Meta:
model = AModel
fields =['a', 'b']
class AFormset(BaseInlineFormSet):
def clean(self):
# Some logic to validate relationships between the forms
但是,测试表单很简单:form = AForm(formdata)
然后根据数据验证其有效性或错误。我在为formset编写测试时遇到了麻烦。
我试过了:
formset = AFormset()
使用modelformset_factory
Formset = modelformset_factory(AModel, AForm, formset=AFormset, fields=('a', 'b'))
formset = Formset(formdata)
使用参数和模拟的各种组合(实例,查询集)。但我总是得到与模型外键或主键相关的错误。一个例子:
Error Traceback (most recent call last):
File "/tests/test_forms.py", line 62, in test_validation formset = Formset(formdata)
File "lib/python2.7/site-packages/django/forms/models.py", line 853, in __init__
self.instance = self.fk.rel.to()
AttributeError: 'AFormset' object has no attribute 'fk'
我错过了什么?有没有更简单的方法来实例化带有数据字典的formset并使其运行clean
方法?我应该只测试使用该表单的视图吗? (在视图中我使用带有Django Extra Views包的表单和formset)
答案 0 :(得分:0)
问题不在于您的测试,而在于您的基本formset类与formset工厂之间的不兼容性。
您的AFormset类继承自BaseInlineFormSet。该类期望存在fk
属性,该属性应该将表单模型的外键确定为它所在的对象" inline"。该属性由inlineformset_factory
函数创建。但是,您正在使用modelformset_factory
来构造具体的formset类;这不会设置fk
属性。
您应该使用inlineformset_factory
(并传入父模型),或者将您的formset类更改为从BaseModelFormSet继承,如果它实际上不是内联的。