I'm starting writing tests for my Pyramid views (using webtest), and coming from a Django background I'm having an hard time trying to understand how to test that certain variables have been passed to the template. For example let's consider this view:
@view_config(route_name='login_or_signup', renderer='login_or_signup.html')
def login_or_sign_up(request):
if request.method == 'POST':
try:
do_business_logic()
return HTTPFound(location=next)
except Invalid as e:
request.response.status_code = 400
return dict(form_errors=e.asdict())
return {}
How can I write a test that proves that if the form is incorrect, a form_errors
dictionary is passed to the template? In Django I would use the context attribute, but in Pyramid/webtest I can't find nothing similar... It seems that template's data is not accessible via the response object. The only thing I found in order to access this data is via event listeners:
@subscriber(BeforeRender)
def print_template_context(event):
for k, v in event.rendering_val.items():
print(k, v)
But I think that is not feasible to use such approach, since:
- it's a global listener
- it has no access to the response object
So... I tried to extend the base Response
class (in order to attach extra fields to it):
class TemplateResponse(Response):
def __init__(self, template, template_context=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self.template = template
self.template_context = template_context or {}
self.text = render(self.template, self.template_context, self.request)
and change the original view to:
@view_config(route_name='login_or_signup')
def login_or_sign_up(request):
if request.method == 'POST':
try:
do_buisness_logic()
return HTTPFound(location=next)
except Invalid as e:
return TemplateResponse(
'login_or_signup.html',
dict(form_errors=e.asdict()),
status=400
)
return TemplateResponse('login_or_signup.html')
But it's helpless, since webtest returns its own TestResponse
object instead of my TemplateResponse
... so how can I test data in templates?