【问题标题】:Unittest Jinja2 and Webapp2 : template not foundUnittest Jinja2 和 Webapp2:找不到模板
【发布时间】:2013-10-24 17:19:41
【问题描述】:

我在一个 GAE 项目中使用 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)。

该应用在开发服务器上运行良好,并且模板已正确呈现。

但是当我尝试对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 环境或模板加载器配置?

【问题讨论】:

标签: google-app-engine jinja2 webapp2


【解决方案1】:

问题根源: Jinja2 默认加载器在相对的./templates/ 目录中搜索文件。当您在开发服务器上运行 GAE 应用程序时,此路径相对于应用程序的根目录。但是当你运行你的单元测试时,这个路径是相对于你的单元测试文件的。

解决方案: 不是一个理想的解决方案,但这是我解决问题的一个技巧。

我更新了 jinja2 工厂以添加动态模板路径,在 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

我在我的单元测试的 setUp 中设置了模板的绝对路径:

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

【讨论】:

  • 谢谢!您可以通过基于包含工厂函数的模块/文件生成绝对路径来避免在配置中设置路径。您已经以这种方式生成了绝对路径,只是您正在测试 setUp 函数中执行此操作。如果您在工厂功能中执行此操作,则无需记住进行任何配置,并且它可以在现场和测试中工作。例如:config = {'template_path': os.path.join(os.path.dirname(__file__), 'templates/')}(假设包含工厂函数的文件和您的模板目录都在项目的根目录下)。
  • 如果可以的话请帮我解决这个问题stackoverflow.com/questions/67661017/…
猜你喜欢
  • 2014-12-23
  • 2021-05-28
  • 1970-01-01
  • 1970-01-01
  • 2012-07-11
  • 2017-07-16
  • 2021-08-12
  • 1970-01-01
  • 2022-01-12
相关资源
最近更新 更多