对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)
1 回答
问题不在于您的测试,而在于您的基本formset类和formset工厂之间的不兼容性 .
您的AFormset类继承自BaseInlineFormSet . 该类期望存在
fk
属性,该属性应该将表单模型的外键确定为它所对应的对象"inline" . 该属性由inlineformset_factory
函数创建 . 但是,您正在使用modelformset_factory
来构造具体的formset类;这不会设置fk
属性 .您应该使用
inlineformset_factory
(并传入父模型),或者更改您的formset类以继承BaseModelFormSet(如果它实际上不是内联的) .