如何在Django类的__init__方法中Mock配置settings值
解决测试中
override_settings在__init__方法不生效的问题 问题核心是**MyClass的实例化(__init__执行)发生在override_settings的配置生效之前**,导致__init__里读取的是原始settings值,而my_method是在测试函数执行期间调用的,此时配置已经被覆盖,所以能读到新值。以下是几个可行的解决办法:
1. 把实例化逻辑移到测试函数内部
直接在测试函数里创建MyClass实例,确保override_settings已经生效后再执行__init__:
@override_settings(EXAMPLE="foo") def test_my_procotol(): # 此时settings已经被覆盖,__init__会读取到"foo" my_instance = MyClass() # 执行测试逻辑 result = my_instance.my_method() # 断言验证结果 assert result is not None
2. 修改代码实现,支持依赖注入
调整MyClass的构造函数,允许外部传入协议实现类,避免在__init__里硬依赖settings:
class MyClass: my_protocol: MyProtocol def __init__(self, protocol_impl: MyProtocol = None) -> None: # 优先使用外部传入的实现,否则按settings创建 if protocol_impl: self.my_protocol = protocol_impl else: if settings.EXAMPLE == "foo": self.my_protocol = Foo() elif settings.EXAMPLE == "bar": self.my_protocol = Bar() def my_method(self) -> Union[int, None]: [...] result = self.my_protocol.another_method() [...]
测试时直接传入指定的实现类,完全绕开settings的依赖:
def test_my_procotol(): # 直接传入Foo实例,不需要修改settings my_instance = MyClass(protocol_impl=Foo()) result = my_instance.my_method() assert result == expected_value
这种方式不仅解决了测试问题,还降低了代码耦合,让业务逻辑更灵活。
3. 使用TestCase类,在setUp中创建实例
如果用Django的TestCase类编写测试,把实例化放在setUp方法里——setUp会在override_settings生效后执行:
from django.test import TestCase, override_settings @override_settings(EXAMPLE="foo") class MyClassTest(TestCase): def setUp(self): # setUp在配置覆盖后执行,__init__能读到正确的settings值 self.my_instance = MyClass() def test_my_protocol(self): result = self.my_instance.my_method() assert result is not None
内容的提问来源于stack exchange,提问作者Joey Fran
相关产品推荐
相关产品推荐

