如何在Django类视图测试中正确修改属性以测试Mixin
问题:测试Django CBV Mixin时触发AttributeError错误
我实现了一个要求类视图(CBV)添加特定属性的Mixin,功能正常,但测试时遇到报错:AttributeError: This method is available only on the class, not on instances.
测试代码如下:
class TestView(GroupRequiredMixin, View): group_required = ("test_group",) raise_exception = True def get(self, request): return HttpResponse("OK") class GroupRequiredMixinTest(TestCase): def setUp(self): group = GroupFactory(name="test_group") self.user = UserFactory(groups=(group,)) def test_view_without_group_required_improperly_configured(self): rfactory = RequestFactory() request = rfactory.get("/fake-path") request.user = self.user view = TestView() view.group_required = None with self.assertRaises(ImproperlyConfigured): view.as_view()(request)
错误栈核心信息:
with self.assertRaises(ImproperlyConfigured): > view.as_view()(request) E AttributeError: This method is available only on the class, not on instances.
错误原因
as_view()是Django CBV的类绑定方法(通过@classonlymethod装饰),只能在视图类上调用,不能在视图实例上调用。你错误地创建TestView实例后调用view.as_view(),触发了该错误。
正确测试方式
方式一:动态修改视图类的属性(复用现有测试类)
直接修改TestView类的属性,测试完成后恢复原值避免污染其他测试:
def test_view_without_group_required_improperly_configured(self): rfactory = RequestFactory() request = rfactory.get("/fake-path") request.user = self.user # 保存原属性值 original_group = TestView.group_required # 修改类属性 TestView.group_required = None try: with self.assertRaises(ImproperlyConfigured): TestView.as_view()(request) finally: # 恢复原属性 TestView.group_required = original_group
方式二:为测试场景创建独立临时视图类
为每个测试场景单独定义视图类,隔离性更好:
def test_view_without_group_required_improperly_configured(self): rfactory = RequestFactory() request = rfactory.get("/fake-path") request.user = self.user # 定义临时视图类,故意不设置group_required class TempMissingGroupView(GroupRequiredMixin, View): raise_exception = True def get(self, request): return HttpResponse("OK") with self.assertRaises(ImproperlyConfigured): TempMissingGroupView.as_view()(request)
方式三:直接调用实例的dispatch方法(推荐测试Mixin逻辑)
Mixin的核心逻辑在dispatch实例方法中,可直接创建视图实例、绑定request后调用dispatch,支持动态修改实例属性:
def test_view_without_group_required_improperly_configured(self): rfactory = RequestFactory() request = rfactory.get("/fake-path") request.user = self.user # 创建视图实例并修改属性 view = TestView() view.group_required = None view.request = request # 手动绑定request到实例 with self.assertRaises(ImproperlyConfigured): view.dispatch(request)
补充说明
你的GroupRequiredMixin中,get_group_required是实例方法,会检查self.group_required,所以修改实例属性的逻辑是有效的,只要绕过as_view()直接测试实例的dispatch方法即可。
内容的提问来源于stack exchange,提问作者Hanny
相关产品推荐
相关产品推荐

