Ruby on rails 4 RSpec Capybara功能测试中的Rails I18n完整错误消息

Ruby on rails 4 RSpec Capybara功能测试中的Rails I18n完整错误消息,ruby-on-rails-4,rspec,internationalization,capybara,Ruby On Rails 4,Rspec,Internationalization,Capybara,我想对我的功能测试应用验证检查,如: click_button 'Submit' expect(page).to have_content "Question can't be blank" 我正在使用I18n功能,希望使用t()helper: expect(page).to have_content t('errors.messages.blank') 但这只检查“不能为空”。但是我需要检查问题字段上的错误。为什么我需要完整的信息?事实上,如果唯一的问题是与字段相关的错误,我们可以用以下

我想对我的功能测试应用验证检查,如:

click_button 'Submit'

expect(page).to have_content "Question can't be blank"
我正在使用I18n功能,希望使用
t()
helper:

expect(page).to have_content t('errors.messages.blank')
但这只检查
“不能为空”
。但是我需要检查
问题
字段上的错误。为什么我需要完整的信息?事实上,如果唯一的问题是与字段相关的错误,我们可以用以下内容来涵盖:

expect(find('.question-wrapper')).to have_content t('errors.messages.blank')
但有时错误出现在表单中未使用的字段上,或者出现在
:base
上。假设我们有一个表单以嵌套属性的形式输入一个问题及其答案(它有一个“添加新答案”按钮,该按钮使用JavaScript创建一组新的
answer
字段),如果表单提交时没有任何答案,则会出现这些错误:

expect(page).to have_content "There should be at least 2 answers"
expect(page).to have_content "Correct answer must be selected"
如何实现这一点?我们无法检查上述
.question wrapper
之类的任何字段,因为
“至少2个答案”
未绑定到任何属性(或者即使是,比如说
答案,也不在表单中),并且由于表单提交时没有任何答案(没有单击),因此正确答案广播不存在我上面提到的“添加新答案”按钮)


我目前正在使用一个黑客助手,如:

# spec/support/helpers/i18n_helpers.rb
def full_error(model_class, attribute, message)
  @_i18n_dummies ||= {}
  @_i18n_dummies[model_class] ||= model_class.new
  @_i18n_dummies[model_class].errors.full_message(
    attribute,
    @_i18n_dummies[model_class].errors.generate_message(attribute, message)
  )
end
要实现上述期望:

# spec/features/question_spec.rb
expect(page).to have_content full_error(Question, :answers, :many) # A custom validator
expect(page).to have_content full_error(Question, :correct_answer, :blank)

整件事都在。

我想说,您可能不应该在测试中使用t()来生成这些字符串,因为这样您就不会真正验证它们是否正确,而只是重新实现如何在测试代码中生成错误字符串,而这并不是真正测试任何东西。@TomWalpole
t()
在您不测试内容,而是生成特定错误时特别有用。要检查内容,您需要逐字写出消息的内容。实际上,这是推荐的方法(thoughtbot等人,goog Rails i18n测试).好的-但是你真的应该在其他地方测试你的i18n翻译,这对我来说似乎是额外的工作。每个人都有自己的翻译。@TomWalpole我不是在这里测试翻译,我唯一关心的是“如果某个内容是空的,希望页面有一条空白消息。”“。由于这是一个多语言应用程序,翻译可能会不时更改,
t()
比直接用默认语言编写错误消息更为脆弱。