Unittest Jinja2 and Webapp2: template not found

I am using Jinja2 with Webapp2 in a GAE project.

I have a RequestHandler base, as described 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:

 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 application works well on the dev server, and the template displays correctly.

But when I try 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') throws an exception: TemplateNotFound: my_template.html .

Is there something I missed? How is jinja2 environment loader or template configuration?

+2
source share
1 answer

Origin of the problem: By default, the Jinja2 boot loader searches for files in the relative ./templates/ directory. When you run the GAE application on the development server, this path refers to the root of your application. But when you run unittests, this path applies to your unittest files.

Solution: Not quite a perfect solution, but here is the trick I did to solve my problem.

I updated jinja2 factory to add the dynamic template path set in app config:

 def jinja2_factory(app): """Set configuration environment for Jinja.""" config = {'template_path': app.config.get('templates_path', 'templates'),} j = jinja2.Jinja2(app, config=config) return j 

And I set the absolute path to the templates in setUp of my unittests:

 class MyHandlerTest(unittest.TestCase): def setUp(self): # Set template path for loader start = os.path.dirname(__file__) rel_path = os.path.join(start, '../../templates') # Path to my template abs_path = os.path.realpath(rel_path) application.config.update({'templates_path': abs_path}) 
+3
source

All Articles