无法在django表单的单元测试中初始化选项字段,其中选择字段从db填充

时间:2018-05-10 07:53:37

标签: django unit-testing django-forms

我有一个django表单,其中选择字段从db填充。

class TestForm(forms.Form):
   CLASS_CHOICE = []
   classes = Class.objects.filter(std__gte=4)
   for cls in classes:
     CLASS_CHOICE.append((cls.code,
                               "{} - {}".format(cls.code,cls.std)))
   name = forms.CharField()
   class = forms.ChoiceField(choices = CLASS_CHOICE)

   def _post_clean(self):
     # some validation
     pass

将单位测试编写为:

class SampleTest(TestCase):

   @classmethod
   def setUpClass(cls):
      super(SampleTest, cls).setUpClass()
      cls.class = Class.objects.create(std=10,code='A')

   def test_valid_form(self):
      post_data = {'name':'testing',
                   'class':'A' }
      f = TestForm(data=post_data)
      self.assertTrue(f.is_valid())

现在的问题是,在运行测试时,首先加载应用程序,然后再初始化db,因此单元测试的setUpClass没有被调用,CLASS_CHOICE保持空白,表单验证失败。在Class表中创建一个条目后,如何避免这种情况或重新初始化选择字段。

1 个答案:

答案 0 :(得分:0)

当你第一次执行包含你的代码的模块时,你设置类选择的方式只会被填充一次。这不太理想,因为:

  • 如果添加了新类,则它们将不可用作选项
  • 当此模块加载到内存中时,可能无法连接数据库,从而导致运行时错误

您需要进行此操作,以便每次创建新表单时动态构建choices。为此,使choices成为可调用函数而不是列表:

def get_class_choices():
    class_choice = []
    classes = Class.objects.filter(std__gte=4)
    for cls in classes:
        class_choice.append((cls.code, "{} - {}".format(cls.code, cls.std)))
    return class_choice


class TestForm(forms.Form):

   name = forms.CharField()
   class = forms.ChoiceField(choices=get_class_choices)

   def _post_clean(self):
     # some validation
     pass