【问题标题】:Add I18n translations to rspec tests将 I18n 翻译添加到 rspec 测试
【发布时间】:2011-03-24 05:30:20
【问题描述】:

如何在我的规范中添加翻译测试?类似的东西:

flash[:error].should == I18n.translate 'error.discovered'

这当然行不通。如何让它发挥作用?

我想确保我收到某个错误。

【问题讨论】:

  • 试试 app.t('error.discovered') 真的没有线索,但也许你很幸运 :)

标签: ruby-on-rails rspec


【解决方案1】:

在我的代码中,一个使用 RSpec 2 的 Rails 3 项目,这正是我写的那一行:

describe "GET 'index'" do
  before do
    get 'index'
  end
  it "should be successful" do
    response.should be_redirect
  end

  it "should show appropriate flash" do
    flash[:warning].should == I18n.t('authorisation.not_authorized')
  end
end

所以我不知道你为什么说不可能?

【讨论】:

  • :O:O 你的语法有效!我的不会。我想如果你像我一样做,你也会得到一个错误。不知道为什么会这样,但这确实是解决方案!
  • 可能是断言右侧缺少括号。
【解决方案2】:

不确定这是否是最佳选择,但在我的 Rails3/RSpec2 应用程序中,我在 RSpec 中按以下方式测试所有语言环境翻译:

我在我的 config/initializers/i18n.rb 文件中设置了可用的语言环境:

I18n.available_locales = [:en, :it, :ja]

在我需要翻译检查的规范文件中,我的测试看起来像:

describe "Example Pages" do   

  subject { page }

  I18n.available_locales.each do |locale|

    describe "example page" do
      let(:example_text) { t('example.translation') }

      before { visit example_path(locale) }

      it { should have_selector('h1', text: example_text) }
      ...
    end
    ...   
  end
end

我不确定如何在不需要 I18n.t 的情况下仅在规范中使用 t() 方法,所以我只是在 spec/support/utilities.rb中添加了一个小便利方法>:

def t(string, options={})
  I18n.t(string, options)
end

更新:这些天来,我倾向于使用i18n-tasks gem 来处理与 i18n 相关的测试,而不是我在上面写的或之前在 StackOverflow 上回答过的内容。

我想在我的 RSpec 测试中使用 i18n,主要是为了确保我对所有内容都有翻译,即没有翻译遗漏。 i18n-tasks 可以通过对我的代码进行静态分析来做到这一点以及更多,因此我不再需要为所有 I18n.available_locales 运行测试(除了测试非常特定于语言环境的功能时,例如,从任何语言环境切换到系统中的任何其他语言环境)。

这样做意味着我可以确认系统中的所有 i18n 键实际上都有值(并且没有一个未使用或已过时),同时保持重复测试的数量,从而降低套件运行时间。

【讨论】:

    【解决方案3】:

    假设控制器中的代码是:

    flash[:error] = I18n.translate 'error.discovered'
    

    您可以存根“翻译”:

    it "translates the error message" do
      I18n.stub(:translate) { 'error_message' }
      get :index # replace with appropriate action/params
      flash[:error].should == 'error_message'
    end
    

    【讨论】:

    • 这并不实际,因为我必须传递错误消息文本。我只想传递翻译标识符 error.discovered。
    • 在这种情况下,您不想测试翻译库是否有效,只需测试您的控制器代码是否调用 translate 方法并将翻译分配给flash[:error]。方法存根替换 I18n.translate 并返回块中传递的值——错误消息文本本身并不重要,它可以是任何你喜欢的。
    • 我实际上想检查 flash[:error] 的消息是否是预期的翻译消息。我这样做的原因是害怕在我的 rspec 测试中将它与其他 flash[:error] 消息混合。例如,我可以检查用户是否有金币并通过 flash[:error] 的测试不应该为 nil。虽然测试成功了,但可能是之前出现了另一个错误。它确实发生了,并且很幸运地发现了它:/
    • 没问题,只需将存根的返回值设置为一些不能与其他错误消息混淆的任意文本。您不想使用实际的翻译,因为 1) 您需要测试每个语言环境; 2)它会使测试变脆
    • 但是如果我用我自己的消息存根翻译,我实际上是在检查翻译过程,对吗?我不想那样做。我想看看是否显示了正确的错误消息。或者也许之前的一些检查填充了错误变量(我倾向于使用 :error 进行闪烁)。我错过了什么吗?
    猜你喜欢
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多