Using webapp2 i18n in unit tests

I am using webapp2 with webapp2_extras.i18n for a Google App Engine application.

I have a unit test script as described below: https://developers.google.com/appengine/docs/python/tools/localunittesting

The test script imports the models and does not include webapp2 handlers, because the goal of the test is business logic code, not requests and responses. However, some of my models will call i18n functions, such as format_currency or gettext , which will result in an error:

 AssertionError: Request global variable is not set. 

How can I initialize the i18n module without instantiating the webapp2 application and request?

+4
source share
4 answers

Try to make fun of your functions.

Example: I have a script called users who import i18n as follows:

 from webapp2_extras.i18n import gettext as _ 

So, in my tests, I mock this function:

 from pswdless.model import PswdUserEmail, EmailUserArc from pswdless.users import FindOrCreateUser from pswdless import users # mocking i18n users._ = lambda s: s #your tests bellow 

You can use the same trick with other features.

Hope this helps you.

0
source

I had the same problem (but for uri_for) and I ended up doing the following in my test:

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

I had to run a trial version and an error to guess which environment variables should be set in the request. You may need to add more to call i18n.

+4
source

It seems pretty simple to mock the i18n. I would prefer this approach because the request and application are really not needed in unit tests.

Here's a sample 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 
0
source

Mocking seems to be the way to go, but the other answers are not complete and / or more complex than necessary. Here is a simple layout that works for me.

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

All Articles