测试 django 国际化 - 模拟 gettext
我正在国际化/i18n-ing 一个 django 项目。我们有一个独立运行并执行后台任务的部分。它是由rabbitmq调用的。我想测试 i18n/l10n 是否适用于该部分。然而,我们的应用程序尚未翻译,并且暂时不会翻译。我想在翻译开始之前编写单元测试。
我想模拟一些翻译,以便 _("anything")
作为常量字符串返回,这样我就可以测试它是否正在尝试翻译内容,而无需我设置所有内容翻译。
我尝试使用 mock,但是 with mock.patch('django.utils .translations.ugettext_lazy'), my_function_that_just_returns_one_string): 不起作用。
_
导入为 from django.utils.translations import ugettext_lazy as _
。
I'm internationalizing/i18n-ing a django project. We have one part that runs independently and performs background tasks. It's called by rabbitmq. I want to test that the i18n/l10n works for that part. However our app isn't translated yet, and won't be for a while. I want to write the unittests before translation begins.
I'd like to mock some translations, so that _("anything")
is returned as a constant string, so that I can test that it's trying to translate things, without me needing to set up all the translations.
I tried using mock, but with mock.patch('django.utils.translations.ugettext_lazy'), my_function_that_just_returns_one_string):
didn't work. The _
is imported as from django.utils.translations import ugettext_lazy as _
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
看来您没有修补正确的模块。如果您的 foo/models.py 具有
from django.utils.translations import ugettext_lazy as _
语句,则_
位于命名空间中foo.models 模块的,这是你必须修补的地方。或者
如果您有多个使用
ugettext_lazy
的模块,那么您可以这样做:不幸的是,没有单行代码可以为所有使用
ugettext_lazy
的模块模拟它,因为一旦函数被导入到模块中,更改 django.utils.translations.ugettext_lazy 就毫无意义了——原始引用将继续指向原始函数。请参阅 https://docs.python.org/3 /library/unittest.mock.html#where-to-patch 了解更多。
It seems you're not patching the correct module. If it's your
foo/models.py
which has thefrom django.utils.translations import ugettext_lazy as _
statement, then_
is in the namespace of thefoo.models
module, and this is where you have to patch.or
If you have multiple modules using
ugettext_lazy
, then you can do it like so:Unfortunately, there is no one-liner to mock it for all modules that use
ugettext_lazy
, because once the function is imported in your modules, it's pointless to changedjango.utils.translations.ugettext_lazy
-- the original references will keep pointing to the original function.See https://docs.python.org/3/library/unittest.mock.html#where-to-patch for more.
您可以执行以下操作来替换默认翻译对象上的
ugettext
方法:You can do the following to replace the
ugettext
method on the default translation object:我找不到现有的方法来做到这一点。然而,通过阅读 Django 源代码,我想出了一种简单、脆弱的方法来做到这一点:查看 _active DjangoTranslation 对象,然后包装它们的 ugettext 方法。我在这里描述了它: http:// /www.technomancy.org/python/django-i18n-test-translation-by-manually-setting-translations/
I couldn't find an existing way to do this. However from reading the Django source code I came up with a hacky, brittle way to do this by looking at the _active DjangoTranslation objects, then wrapping their ugettext methods. I've described it here: http://www.technomancy.org/python/django-i18n-test-translation-by-manually-setting-translations/
我看过你的解决方案,我认为当你没有提供翻译字符串时测试 i18n 支持既巧妙又简单。但我担心
translation
包只是一个始终有效的东西,我们认为这是理所当然的,所以在大量注释的测试代码中看到它的内部结构至少会让我在恐惧中逃跑(笑)。我认为创建一个测试应用程序,添加到测试设置中的
INSTALLED_APPS
中,提供自己的翻译是一种更简洁的方法。您的测试将被简化为translation.activate('fr'); self.assertEqual('xxx_anything', gettext('anything'), '应该激活 i18n 支持。')
。通过简单的测试,其他开发人员可以快速跟进并看到测试应用程序的包包含一个
/locale
目录,该目录应该立即记录您的方法。I've looked at your solution and I think it's both ingenious and simple for testing i18n support when you have no translation strings provided. But I'm afraid the
translation
package is just something that always works and which we take for granted, so seeing it's internals in heavily commented test code would, at least, make me run off in fear (chuckle).I think creating a test application, added to
INSTALLED_APPS
in test settings, which provides it's own translations is a much cleaner approach. Your tests would be simplified totranslation.activate('fr'); self.assertEqual('xxx_anything', gettext('anything'), 'i18n support should be activated.')
.With simple tests, other developers could quickly follow-up and see that the test app's package contains a
/locale
directory, which should immediately document your approach.