如何在Django TestCase中用parameterized装饰器引用类中MY_LIST
问题分析与解决
错误原因
- 变量名拼写错误:装饰器中写的是
MYLIST,但类中定义的是MY_LIST,大小写与下划线不匹配。 - setUpClass调用方式错误:
setUpClass是类方法,调用后返回None,链式调用.MYLIST自然触发NoneType属性错误;且手动实例化类调用该方法不符合Django测试框架的执行流程。 - 装饰器执行时机问题:
parameterized.expand在类加载阶段就会解析参数,而setUpClass是测试类准备阶段才执行的,直接引用类属性会导致参数尚未初始化。
正确实现方式
方式一:类属性+延迟加载参数
在setUpClass中完成数据初始化(必须调用父类方法初始化测试环境),通过lambda延迟获取类属性,避免装饰器执行时参数未就绪:
from django.test import TestCase from parameterized import parameterized from .models import MyModel class MyTest(TestCase): @classmethod def setUpClass(cls): super().setUpClass() # 必须调用父类方法,初始化测试数据库等环境 myobj = MyModel.objects.create() cls.MY_LIST = [ ({ 'key1': {'a': myobj.id, 'b': 2}},), ({ 'key2': {'a': myobj.id, 'b': 2}},), ] @parameterized.expand(lambda: MyTest.MY_LIST) def test_mytest(self, dict_item): print(dict_item.items())
方式二:独立封装参数生成方法
将测试参数的生成逻辑封装为类方法,直接在装饰器中调用,无需依赖setUpClass:
from django.test import TestCase from parameterized import parameterized from .models import MyModel class MyTest(TestCase): @classmethod def generate_test_params(cls): myobj = MyModel.objects.create() return [ ({ 'key1': {'a': myobj.id, 'b': 2}},), ({ 'key2': {'a': myobj.id, 'b': 2}},), ] @parameterized.expand(generate_test_params()) def test_mytest(self, dict_item): print(dict_item.items())
注意事项
- 确保Django测试数据库已正确初始化,避免创建
MyModel对象时出错。 - 使用方式一时,不要手动调用
setUpClass,Django测试框架会自动在所有测试方法执行前调用该方法。
内容的提问来源于stack exchange,提问作者alias51
相关产品推荐
相关产品推荐

