【问题标题】:Not able to initialise choice fields in Unit test for django form where choice field is getting populated from db无法在 django 表单的单元测试中初始化选择字段,其中选择字段是从 db 填充的
【发布时间】:2018-10-20 10:39:43
【问题描述】:

我有一个 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 表中创建一个条目后,如何避免这种情况或重新初始化选择字段。

【问题讨论】:

    标签: django unit-testing django-forms


    【解决方案1】:

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

    • 如果添加了新类,它们将无法作为选择选项使用
    • 此模块加载到内存时可能没有连接数据库,导致运行时错误

    您需要使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
    

    【讨论】:

      猜你喜欢
      • 2017-03-15
      • 2011-06-05
      • 2018-07-05
      • 2018-11-10
      • 2021-09-29
      • 2013-04-06
      • 2015-11-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多