测试 Django 视图:我们怎么知道捕获的异常是否真的被引发了?
Testing Django view: how can we know if catched exception was actually raised?
我想测试我的观点中的异常是否按预期出现。我面临的 "issue" 是我在我看来使用 try
和 except
语句,所以我实际上 catch 那些异常(按顺序当他们被提出时做一些事情)。
我的问题如下:如果在我的 except
语句中发现了预期的 exception
,我该如何测试?
例如:
myviews.py
class SomeView(LoginRequiredMixin, CreateView):
model = models.MyModel
template_name = "my_template.html"
form_class = forms.MyForm
def form_valid(self, form):
try:
# normal stuff here
return super(SomeView, self).form_valid(form)
except Exception1 as e:
# some other stuff here
print("Exception1 occured: ", e)
messages.error(self.request, "Message1")
return self.render_to_response(self.get_context_data(form=form))
except Exception2 as e:
# some other stuff here
print("Exception2 occured: ", e)
messages.error(self.request, "Message2")
return self.render_to_response(self.get_context_data(form=form))
except Exception as e:
# some other stuff here
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):
# test: everything must works just fine
form_data = some_valid_data
response = self.client.post("some_url", form_data)
self.assertEqual(response.status_code, 200)
# test: Exception1 should be raised in SomeView
form_data = some_NOT_valid_data # on purpose
response = self.client.post(reverse("some_url"), form_data)
for message in list(response.context['messages']): print(message)
# UPDATE1 - no message is print,
# even if they are displayed as expected on my real web page
# when doing willingly bad stuff
非常感谢您的帮助!
更新1
本来想做的:
form_data = some_NOT_valid_data
self.assertRaises(
Exception1,
lambda: self.client.post("some_url"), form_data)
)
但后来我改变了对 jonrsharpe 评论的看法(测试行为多于实现)。因此,当 Exceptions
被捕获时,我尝试获取生成的错误消息,以便我能够检查它们是否符合我的预期。但是我显然无法获得任何 context message
,即使它们在我的模板中按预期显示也是如此!然而 context
不是空的。
更新 2 - 回答我自己的问题
我终于找到了管理方法。例如,我尝试添加 follow=True
(如 response = self.client.post("some_url", form_data, follow=True)
,但这是不正确的,因为它不是重定向,而是使用不同的上下文再次呈现相同的视图。因此,我所做的如下:
对于我认为的每个 except
语句:
except Exception1 as e:
# some other stuff here
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))))
此外,在我看来,我重写了我的 get_context_data
方法:
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 = self.client.post("some_url", form_data)
self.assertTrue("part_of_message" in str(response.context.get('messages')[0]))
而且有效!
我终于成功了(见我自己的更新2),@jonrsharpe的指示。测试行为比一开始完全测试我想要的要好(如果 exception
被引发,然后被捕获)。所以我努力测试错误 messages
是否正确生成,在纠正了我自己的一些错误后,我终于得到了一些有用的东西!或者没有工作,但正如预期的那样:你明白了。
我想测试我的观点中的异常是否按预期出现。我面临的 "issue" 是我在我看来使用 try
和 except
语句,所以我实际上 catch 那些异常(按顺序当他们被提出时做一些事情)。
我的问题如下:如果在我的 except
语句中发现了预期的 exception
,我该如何测试?
例如:
myviews.py
class SomeView(LoginRequiredMixin, CreateView):
model = models.MyModel
template_name = "my_template.html"
form_class = forms.MyForm
def form_valid(self, form):
try:
# normal stuff here
return super(SomeView, self).form_valid(form)
except Exception1 as e:
# some other stuff here
print("Exception1 occured: ", e)
messages.error(self.request, "Message1")
return self.render_to_response(self.get_context_data(form=form))
except Exception2 as e:
# some other stuff here
print("Exception2 occured: ", e)
messages.error(self.request, "Message2")
return self.render_to_response(self.get_context_data(form=form))
except Exception as e:
# some other stuff here
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):
# test: everything must works just fine
form_data = some_valid_data
response = self.client.post("some_url", form_data)
self.assertEqual(response.status_code, 200)
# test: Exception1 should be raised in SomeView
form_data = some_NOT_valid_data # on purpose
response = self.client.post(reverse("some_url"), form_data)
for message in list(response.context['messages']): print(message)
# UPDATE1 - no message is print,
# even if they are displayed as expected on my real web page
# when doing willingly bad stuff
非常感谢您的帮助!
更新1
本来想做的:
form_data = some_NOT_valid_data
self.assertRaises(
Exception1,
lambda: self.client.post("some_url"), form_data)
)
但后来我改变了对 jonrsharpe 评论的看法(测试行为多于实现)。因此,当 Exceptions
被捕获时,我尝试获取生成的错误消息,以便我能够检查它们是否符合我的预期。但是我显然无法获得任何 context message
,即使它们在我的模板中按预期显示也是如此!然而 context
不是空的。
更新 2 - 回答我自己的问题
我终于找到了管理方法。例如,我尝试添加 follow=True
(如 response = self.client.post("some_url", form_data, follow=True)
,但这是不正确的,因为它不是重定向,而是使用不同的上下文再次呈现相同的视图。因此,我所做的如下:
对于我认为的每个 except
语句:
except Exception1 as e:
# some other stuff here
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))))
此外,在我看来,我重写了我的 get_context_data
方法:
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 = self.client.post("some_url", form_data)
self.assertTrue("part_of_message" in str(response.context.get('messages')[0]))
而且有效!
我终于成功了(见我自己的更新2),@jonrsharpe的指示。测试行为比一开始完全测试我想要的要好(如果 exception
被引发,然后被捕获)。所以我努力测试错误 messages
是否正确生成,在纠正了我自己的一些错误后,我终于得到了一些有用的东西!或者没有工作,但正如预期的那样:你明白了。