I use Jinja2 with Webapp2 on a GAE project.
I have a base RequestHandler
as describe in webapp2_extras.jinja2
:
import webapp2
from webapp2_extras import jinja2
def jinja2_factory(app):
"""Set configuration environment for Jinja."""
config = {my config...}
j = jinja2.Jinja2(app, config=config)
return j
class BaseHandler(webapp2.RequestHandler):
@webapp2.cached_property
def jinja2(self):
# Returns a Jinja2 renderer cached in the app registry.
return jinja2.get_jinja2(factory=jinja2_factory, app=self.app)
def render_response(self, _template, **context):
# Renders a template and writes the result to the response.
rv = self.jinja2.render_template(_template, **context)
self.response.write(rv)
And a view handler as:
class MyHandler(BaseHandler):
def get(self):
context = {'message': 'Hello, world!'}
self.render_response('my_template.html', **context)
My templates are in the default location (templates
).
The app works well on dev server, and the template is correctly rendered.
But when I try to unittest MyHandler
with
import unittest
import webapp2
import webstest
class MyHandlerTest(unittest.TestCase):
def setUp(self):
application = webapp2.WSGIApplication([('/', MyHandler)])
self.testapp = webtest.TestApp(application)
def test_response(self):
response = application.get_response('/')
...
application.get_response('/my-view')
raise an exception: TemplateNotFound: my_template.html
.
Is there something I missed? Like a jinja2 environment or template loader configuration?
Problem origin: Jinja2 default loader searches files in a relative
./templates/
directory. When you run your GAE application on the development server this path is relative to the root of your application. But when you run your unittests this path is relative to your unittest files.Solution: Not really an ideal solution, but here a trick I did to solve my problem.
I updated the jinja2 factory to add a dynamic template path, set in app config:
And I set an absolute path to the templates in the setUp of my unittests: