在单元测试中使用webapp2 i18n

时间:2013-02-19 15:19:26

标签: unit-testing google-app-engine internationalization webapp2

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

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

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

AssertionError: Request global variable is not set.

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

4 个答案:

答案 0 :(得分: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。

答案 1 :(得分: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

您可以将其他功能用于相同的技巧。

我希望它可以帮到你。

答案 2 :(得分:0)

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

这是一个示例pytest fixture:

@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

答案 3 :(得分:0)

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

=== 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")