如何在 Django 的单元测试中禁用翻译?

12
我正在使用Django国际化工具翻译我的应用程序中的一些字符串。代码如下:
from django.utils.translation import ugettext as _
def my_view(request):
    output = _("Welcome to my site.")
    return HttpResponse(output)

接下来,我将使用Django测试客户端编写单元测试。这些测试向视图发出请求并比较返回的内容。

我如何在运行单元测试时禁用翻译?我的目标是这样做:

class FoobarTestCase(unittest.TestCase):
    def setUp(self):
        # Do something here to disable the string translation. But what?
        # I've already tried this, but it didn't work:
        django.utils.translation.deactivate_all()
    def testFoobar(self):
        c = Client()
        response = c.get("/foobar")
        # I want to compare to the original string without translations.
        self.assertEquals(response.content.strip(), "Welcome to my site.")
3个回答

14

在测试客户端上调用.get().post()将运行所有配置的中间件。这意味着它也会运行LocaleMiddleware,该中间件将调用translation.get_language_from_request(),然后是translation.activate(language)

这意味着在使用测试客户端编写测试时,当前活动语言将被忽略和丢弃。换句话说,以下代码不起作用:

def testFoobar(self):
    c = Client()
    # This will not work.
    translation.deactivate_all()
    # This will not work either.
    translation.activate('en-us')
    # The next call will override the earlier activate/deactivate calls.
    response = c.get("/foobar")

有几个解决方案:

  1. 在会话对象中设置所需的语言。
  2. 在 cookie 中设置所需的语言。
  3. 发送 HTTP_ACCEPT_LANGUAGE 标头。
  4. 设置 settings.LANGUAGE_CODE

来源(来自 Django 1.4,但自 1.1 或更早以来基本未改变):


11

我使用@Denilson Sá回答中的第4种方法解决了同样的问题。结果发现这不需要任何特定于测试的设置文件,并且可以通过django提供的装饰器或上下文管理器在每个测试的基础上定义(请参见覆盖设置)。

它可以像这样使用:

from django.test import TestCase, override_settings

class MyTest(TestCase):
    @override_settings(LANGUAGE_CODE='en-US', LANGUAGES=(('en', 'English'),))
    def test_mypage(self):
        // ...

装饰器也可以应用于整个TestCase子类,或者为了更精细的控制,还有一个上下文管理器(请参见上面链接的文档)。

对我来说,这相当常见,我还定义了:

english = override_settings(
    LANGUAGE_CODE='en-US',
    LANGUAGES=(('en', 'English'),),
)

现在我可以在需要使用英语的测试用例中简单地使用@english


1
我认为在单元测试中,将语言强制设置为已知设置会更有意义。这意味着您正在测试更接近实际实现的内容。
要激活特定语言,您可以在设置中执行以下操作:
from django.utils.translation import activate
...
activate('en-en')

这可能是个好主意,你有关于如何实现它的建议吗? - Denilson Sá Maia
2
你的回答不可行,因为我在我的答案中已经解释了原因。不过很好尝试,只是它确实行不通。 - Denilson Sá Maia
1
谢谢,帮助我测试了我的视图,我刚刚将本地化设置为“en”,一切都很顺利 :) - Eduard Sukharev

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