2013-10-16 67 views
2

我在GAE項目上使用Jinja2和Webapp2。單元測試Jinja2和Webapp2:找不到模板

我有一個底座作爲RequestHandler描述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) 

和一個視圖處理程序爲:

class MyHandler(BaseHandler): 
    def get(self): 
     context = {'message': 'Hello, world!'} 
     self.render_response('my_template.html', **context) 

我的模板是在默認位置(templates)。

該應用程序在dev服務器上運行良好,並且模板被正確呈現。

但是,當我試圖單元測試MyHandler

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')拋出異常:TemplateNotFound: my_template.html

有什麼我錯過了什麼?像jinja2環境或模板加載器配置?

回答

3

問題來源: Jinja2默認加載程序在相對./templates/目錄中搜索文件。在開發服務器上運行GAE應用程序時,此路徑與應用程序的根目錄相關。但是當你運行你的單元測試時,這個路徑是相對於你的單元測試文件。

解決方案: 不是一個真正理想的解決方案,但這裏有一個技巧,我做了解決我的問題。

我更新了Jinja2的工廠增加一個動態模板路徑,在應用程序配置設置:

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 

而且我在單元測試的設置設定爲模板的絕對路徑:

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}) 
+0

謝謝!您可以通過基於包含工廠功能的模塊/文件生成絕對路徑來避免必須在配置中設置路徑。您已經以這種方式生成了一條絕對路徑,只不過是您在測試setUp函數中完成的。如果你在工廠功能中做到這一點,你將不必記得做任何配置,它可以正常工作和正在測試。例如:'config = {'template_path':os.path.join(os.path.dirname(__ file__),'templates /')}'(假設包含工廠函數和模板目錄的文件都位於該項目)。 – bszom