【问题标题】:Rspec for mailers with I18n带有 I18n 的邮件的 Rspec
【发布时间】:2012-12-02 06:09:46
【问题描述】:

我不明白如何使用 rspec 和国际化进行测试。 例如,在请求测试中我会做

I18n.available_locales.each do |locale|
  visit users_path(locale: locale)
  #...
end

它工作得很好:每个语言环境都测试正确。

但在邮件中,这个技巧不起作用。

user_mailer_spec.rb

require "spec_helper"

describe UserMailer do
  I18n.available_locales.each do |locale|
    let(:user) { FactoryGirl.build(:user, locale: locale.to_s) }
    let(:mail_registration) { UserMailer.registration_confirmation(user) }

    it "should send registration confirmation" do
      puts locale.to_yaml
      mail_registration.body.encoded.should include("test") # it will return error with text which allow me to ensure that for each locale the test call only :en locale email template
    end
  end
end

它运行几次(与我的语言环境一样多),但每次它只为默认语言环境生成 html。

当我从控制器调用UserMailer.registration_confirmation(@user).deliver 时,它工作正常。

user_mailer.rb

...
def registration_confirmation(user)
  @user = user
  mail(to: user.email, subject: t('user_mailer.registration_confirmation.subject')) do |format|
      format.html { render :layout => 'mailer'}
      format.text
  end
end
...

views/user_mailer/registration_confirmation.text.erb

<%=t '.thx' %>, <%= @user.name %>.
<%=t '.site_description' %>
<%=t '.credentials' %>:
<%=t '.email' %>: <%= @user.email %>
<%=t '.password' %>: <%= @user.password %>
<%=t '.sign_in_text' %>: <%= signin_url %>
---
<%=t 'unsubscribe' %>

我再说一遍 - 它适用于所有语言环境。 我只有关于 rspec 测试的问题。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 rspec internationalization actionmailer


    【解决方案1】:

    我认为您可能必须将测试包装在 describe/context 块中,以允许 it 块查看您的 let 变量:

    require "spec_helper"
    
    describe UserMailer do
      I18n.available_locales.each do |locale|
        describe "registration" do
          let(:user) { FactoryGirl.build(:user, locale: locale.to_s) }
          let(:mail_registration) { UserMailer.registration_confirmation(user) }
    
          it "should send registration confirmation" do
            puts locale.to_yaml
            mail_registration.body.encoded.should include("test")
          end
        end
        # ...
      end
      # ...
    end
    

    至于为什么,也许this StackOverflow answer on let variable scoping 会有所帮助。

    编辑

    问题是您为用户分配了区域设置,但您没有将其传递给任何地方的mail 方法吗?也许this StackOverflow answer 可以作为参考。希望两个答案之一与您的情况相关。这是我根据您的情况调整第一个答案的简单尝试(显然未经测试):

    user_mailer.rb

    ...
    def registration_confirmation(user)
      @user = user
      I18n.with_locale(user.locale) do
        mail(to: user.email, 
                 subject: t('user_mailer.registration_confirmation.subject')) do |format|
          format.html { render :layout => 'mailer' }
          format.text
        end
      end
    end
    ... 
    

    【讨论】:

    • 谢谢,保罗,但它不起作用。变量工作正常。如您所见,它已经包含在describe UserMailer 块中。这是为所有测试定义变量的方法。
    • 好吧,我的第二个想法是mail 方法可能需要将语言环境传递给它。请参阅我的编辑和其中提到的 StackOverflow 链接。希望这与@eugen 的回答不太相似。
    • 谢谢,保罗。我的 user_mailer.rb 实际上没有提及任何语言环境。但是..它工作正常。我对其进行了测试,它会根据语言环境发送不同的电子邮件。这就是为什么我说我不明白它是如何工作的:) 不过我尝试了你的建议。实施后 rspec 预期默认语言环境,并且每次都获得非默认语言环境,适用于所有语言环境。有点奇怪。还是谢谢你。
    • 是的,这很奇怪......如果你最终得到了解决方案,请分享!
    【解决方案2】:

    您可能需要指定语言环境,如下所示:

    mail_subscribe.body.encoded.should include(t('user_mailer.subscribe_confirmation.stay', locale: locale))

    您也可以尝试在registration_confirmation 方法中的mail 调用之前添加I18n.locale = user.locale

    【讨论】:

    • 那么在没有看到 UserMailer 的整个代码和测试的情况下,没有什么其他建议了。另一件事是在let 块中定义mail_registration,但在实际测试中你使用mail_subscribe - 这似乎是不一致的,但同样,没有看到整个代码我不能说。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 1970-01-01
    • 2020-07-16
    • 2012-04-26
    • 1970-01-01
    相关资源
    最近更新 更多