测试Django视图:如何验证捕获的异常是否实际触发?
问题:如何测试Django视图中被try-except捕获的异常是否触发?
我在Django视图里用try-except捕获了几个异常,目的是在异常触发时返回错误消息并渲染页面,但不知道怎么验证这些异常确实被正确捕获并执行了对应的处理逻辑。
原视图代码(myviews.py)
class SomeView(LoginRequiredMixin, CreateView): model = models.MyModel template_name = "my_template.html" form_class = forms.MyForm def form_valid(self, form): try: # 正常业务逻辑 return super(SomeView, self).form_valid(form) except Exception1 as e: # 异常处理逻辑 print("Exception1 occured: ", e) messages.error(self.request, "Message1") return self.render_to_response(self.get_context_data(form=form)) except Exception2 as e: # 异常处理逻辑 print("Exception2 occured: ", e) messages.error(self.request, "Message2") return self.render_to_response(self.get_context_data(form=form)) except Exception as e: # 异常处理逻辑 print("Something unexpected occured! ", e) messages.error(self.request, "Message_unexpected") return self.render_to_response(self.get_context_data(form=form))
原测试代码(mytests.py)
def test_SomeView(self): # 测试正常流程 form_data = some_valid_data response = self.client.post("some_url", form_data) self.assertEqual(response.status_code, 200) # 测试Exception1触发场景 form_data = some_NOT_valid_data # 构造无效数据 response = self.client.post(reverse("some_url"), form_data) for message in list(response.context['messages']): print(message) # 更新1:无消息输出,但实际网页中触发异常时能正常显示消息
遇到的卡点
一开始我想用self.assertRaises直接断言异常,但遵循测试行为而非实现的原则,改为检查捕获异常时生成的错误消息,却发现从response.context里拿不到messages——虽然页面上能正常显示这些消息。
最终解决方案
经过调试,我找到了可行的解决办法,分三步操作:
在视图的except块中返回时传入messages参数
修改每个except块的返回语句,把当前请求的messages主动传入上下文:except Exception1 as e: # 异常处理逻辑 print("Exception1 occured: ", e) messages.error(self.request, "Message1") return self.render_to_response( context=self.get_context_data( form=form, messages=list(messages.get_messages(self.request)) ) )其他except块做同样修改即可。
重写视图的
get_context_data方法
让视图能接收并传递messages到最终的上下文字典中:def get_context_data(self, **kwargs): context = super(SomeView, self).get_context_data(**kwargs) if 'messages' in kwargs: context['messages'] = kwargs['messages'] return context在测试中验证错误消息
现在可以正常从response.context里获取messages并断言:response = self.client.post("some_url", form_data) self.assertTrue("Message1" in str(response.context.get('messages')[0]))
这样就能正确验证异常是否被捕获并触发了对应的错误消息逻辑。
内容的提问来源于stack exchange,提问作者KrazyMax
相关产品推荐
相关产品推荐

