4

我将 webapp2 与 webapp2_extras.i18n 一起用于 Google App Engine 应用程序。

我有一个单元测试脚本,如底部所述:https ://developers.google.com/appengine/docs/python/tools/localunittesting

测试脚本导入模型并且不包括 webapp2 处理程序,因为测试的目标是业务逻辑代码,而不是请求和响应。但是,我的一些模型会调用 i18n 函数,例如format_currencyorgettext这会导致错误:

AssertionError: Request global variable is not set.

如何在不实例化 webapp2 应用程序和请求的情况下初始化 i18n 模块?

4

4 回答 4

4

我遇到了同样的问题(但对于 uri_for),我最终在测试中执行了以下操作:

app = webapp2.WSGIApplication(
        [webapp2.Route('/', None, name='upload_handler')])

request = webapp2.Request({'SERVER_NAME':'test', 'SERVER_PORT':80,
    'wsgi.url_scheme':'http'})
request.app = app
app.set_globals(app=app, request=request)

# call function that uses uri_for('upload_handler')

我不得不反复试验来猜测必须在请求中设置哪些环境变量。也许您需要添加更多才能调用 i18n。

于 2013-04-10T18:10:09.333 回答
0

尝试模拟您的功能。

示例:我有一个名为 users 的脚本,它像这样导入 i18n:

from webapp2_extras.i18n import gettext as _

所以在我的测试中,我模拟了这样的函数:

from pswdless.model import PswdUserEmail, EmailUserArc
from pswdless.users import FindOrCreateUser
from pswdless import users

# mocking i18n
users._ = lambda s: s

#your tests bellow

您可以将相同的技巧与其他功能一起使用。

我希望它对你有帮助。

于 2013-09-06T04:17:19.387 回答
0

模拟 i18n 本身似乎很简单。我更喜欢这种方法,因为在单元测试中确实不需要 Request 和 app 。

这是一个示例 pytest 夹具:

@pytest.fixture
def mock_i18n(monkeypatch):

    class MockI18n:

        def set_locale(self, locale):
            pass

        def gettext(self, string, **variables):
            return string

    mock_i18n = MockI18n()

    def mock_get_i18n(factory=None, key=None, request=None):
        return mock_i18n

    from webapp2_extras import i18n
    monkeypatch.setattr(i18n, 'get_i18n', mock_get_i18n)

    yield
于 2016-12-18T13:49:58.890 回答
0

模拟似乎确实是这里的方法,但其他答案并不完整和/或比必要的更复杂。这是一个对我有用的简单模拟。

=== my_module.py ===

from webapp2_extras.i18n import gettext as _

def f(x):
    return _(x)

=== test_my_module.py ===

import my_module

def _mock(x):
    return x

@mock.patch("my_module._", side_effect=_mock)
def test_f(self, foo):
    y = my_module.f("hello")
    self.assertEqual(y, "hello")
于 2017-02-11T03:30:45.827 回答