测试Django国际化-模拟gettext

7
我正在国际化/本地化一个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 _

抱歉问一个奇怪的问题,但是为什么你想要测试已经被测试过的东西 - https://github.com/bx2/django/blob/master/tests/regressiontests/i18n/tests.py#L46?TDD的基本规则教我们要相信其他开发人员。我认为你试图做的是一种过度设计。Django的i18n框架已经被证明是可行的,并且已经进行了测试 - 为什么要让事情变得更加复杂呢?;) - bx2
我的代码使用了Django的翻译功能,但它在一个独立的进程中运行,而不是为Web请求提供服务。我想测试它是否能够在不同的请求中进行翻译。 - Amandasaurus
4个回答

3
您可以按照以下步骤替换默认翻译对象上的ugettext方法:
from django.utils.translation.trans_real import get_language, translation

translation(get_language()).ugettext = mock_ugettext

2

2
我看了你的解决方案,认为它既巧妙又简单,适用于在没有提供翻译字符串时测试i18n支持。但我担心translation包只是一直工作并且我们认为理所当然的东西,因此看到它在大量注释的测试代码中的内部结构,至少会让我感到恐惧(咯咯笑)。
我认为创建一个测试应用程序,添加到测试设置中的INSTALLED_APPS中,该应用程序提供自己的翻译,是一个更清晰的方法。您的测试将简化为translation.activate('fr'); self.assertEqual('xxx_anything', gettext('anything'), 'i18n support should be activated.')
通过简单的测试,其他开发人员可以快速跟进,并查看测试应用程序包含一个/locale目录,这应立即记录您的方法。

1

看起来您没有打补丁到正确的模块。如果您的foo/models.py中有from django.utils.translations import ugettext_lazy as _语句,那么_foo.models模块的命名空间中,这就是您需要打补丁的地方。

with mock.patch('foo.models._', return_value='MOCKED_TRANSLATION'):
    ...

或者

with mock.patch('foo.models._') as mock_ugettext_lazy:
    mock_ugettext_lazy.side_effect = lambda x: x + ' translated'
    ...
    assert translated_text = 'example_text translated'

如果您有多个模块使用ugettext_lazy,则可以这样做:
with mock.patch('foo.models._', side_effect=mock_translator), \
     mock.patch('bar._', side_effect=mock_translator):
    ...

很不幸,对于所有使用ugettext_lazy的模块进行嘲笑的方法无法一句话解决,因为一旦该函数在您的模块中导入,更改django.utils.translations.ugettext_lazy就毫无意义了--原始引用将继续指向原始函数。

有关更多信息,请参见https://docs.python.org/3/library/unittest.mock.html#where-to-patch


我们能把被接受的解决方案移到这个上面吗?这样会更有意义! - Skratt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接