如何在Rspec测试中模拟丢失的I18n键?我有一个帮助器,如果它可用,它看起来使用I18n键。我不知道如何在不可用时创建测试用例。基于控制台测试我很确定帮助方法是正确的,但我不知道如何构建针对该结果的测试(当没有设置所有三种可能的标题类型时)。
# app/helpers/application_helper.rb
def available_page_title
title = ""
case
when content_for?(:page_title)
title = content_for(:page_title)
when !@page_title.nil?
title = @page_title
when I18n.exists?('page_title.default')
title = t('page_title.default')
end
end
-
# config/locales/en.yml
en:
page_title:
delimiter: ' - '
default: Default Page Title
admin_namespace: 'Admin'
# spec/helpers/application_helper.rb
describe 'available_page_title' do
it '(1) returns the the translation title if no other titles set' do
allow(I18n).to receive(:t).with('page_title.default').and_return("Test Title from i18n")
@page_title = nil
expect(helper.available_page_title).to eq(t('page_title.default'))
end
it '(2) returns the the @page_title if it exists and no content_for exists' do
allow(I18n).to receive(:t).with('page_title.default').and_return("Test Title from i18n")
translation_title = t('page_title.default')
@page_title = "Test Title from @page_title"
expect(helper.available_page_title).to eq(@page_title)
end
it '(3) returns the the content_for title if it exists' do
allow(I18n).to receive(:t).with('page_title.default').and_return("Test Title from i18n")
translation_title = t('page_title.default')
@page_title = "Test Title from @page_title"
helper.content_for(:page_title, 'Test Title from content_for')
expect(helper.available_page_title).to eq('Test Title from content_for')
end
it '(4) returns a blank string if no titles are found' do
# Things I've tried...
# I18n.backend.store_translations(:en, { page_title: { default: '' }})
# I18n.backend.store_translations(:en)
# I18n.backend.store_translations(:en, { nil })
# I18n.backend.store_translations()
# I18n.backend = I18n::Backend::Simple.new
allow(I18n).to receive(:t).with('page_title.default').and_return(nil)
@page_title = nil
expect(helper.available_page_title).to eq('')
end
end
以下是测试结果:
$ bundle exec rspec spec/helpers/application_helper_spec.rb:130
Run options: include {:locations=>{"./spec/helpers/application_helper_spec.rb"=>[130]}}
Randomized with seed 14478
ApplicationHelper
available_page_title
(3) returns the the content_for title if it exists
(1) returns the the translation title if no other titles set
(2) returns the the @page_title if it exists and no content_for exists
(4) returns a blank string if no titles are found (FAILED - 1)
Failures:
1) ApplicationHelper available_page_title should (4) return a blank string if no titles are found
Failure/Error: expect(helper.available_page_title).to eq('')
expected: ""
got: "Default Page Title"
(compared using ==)
# ./spec/helpers/application_helper_spec.rb:160:in `block (3 levels) in <top (required)>'
Finished in 0.69197 seconds (files took 4.32 seconds to load)
4 examples, 1 failure
Failed examples:
rspec ./spec/helpers/application_helper_spec.rb:152 # ApplicationHelper available_page_title should (4) return a blank string if no titles are found
Randomized with seed 14478
更新2017-05-31
@ gwcodes的回答有点帮助,但仍未正确设置测试。
allow(I18n).to receive(:translate).with('page_title.default').and_return(nil)
使用该行设置测试,以便实际上仍然存在键page_title.default
,但其值为nil。那没用。
我的帮助方法检查的是密钥的存在。这是当前测试情况的pry输出:
[5] pry(#<RSpec::ExampleGroups::ApplicationHelper::AvailablePageTitle>)> I18n.translate('page_title.default')
=> nil
[6] pry(#<RSpec::ExampleGroups::ApplicationHelper::AvailablePageTitle>)> I18n.exists?('page_title.default')
=> true
[7] pry(#<RSpec::ExampleGroups::ApplicationHelper::AvailablePageTitle>)> I18n.t('page_title.default').empty?
=> false
所以问题仍然存在。如何设置测试环境以便检查是否存在I18n键?
答案 0 :(得分:2)
我正在考虑将您的第一个解决方案用于共享上下文。
# spec/support/i18n_stubs.rb
RSpec.shared_context 'i18n stubs' do
def stub_i18n_value_with_nil(key)
allow(I18n).to receive(:t).with(key).and_return(nil)
allow(I18n).to receive(:exists?).with(key).and_return(false)
end
end
然后在规范帮助文件中添加require support/i18n_stubs
。在您的spec文件需要的任何地方,您只需简单地放置include_context 'i18n stubs'
并在做断言之前调用stub_i18n_value_with_nil('some.i18n.key')
。
例如在spec文件中:
require 'spec_helper'
RSpec.describe 'some_file_or_class' do
include_context 'i18n stubs'
describe 'available_page_title' do
context 'when i18n key is not present' do
before(:each) do
stub_i18n_value_with_nil('some.i18n.key')
end
it 'returns blank string' do
# do assertion here
end
end
end
end
答案 1 :(得分:0)
我确实拿出了一个解决方案,将I18n后端用于测试(虽然它看起来有点像球头锤方法)。
我创建了spec / support / i18n_simple_stub.rb:
module I18n
module Backend
class SimpleStub
def exists?(key, *args)
false
end
end
end
end
然后在该(先前失败的)测试中设置后端。这是新测试:
it '(4) returns a blank string if no titles are found' do
# Sets exists? method to false
I18n.backend = I18n::Backend::SimpleStub.new
@page_title = nil
expect(helper.available_page_title).to eq('')
end
如果有人有更好的方法,我很乐意听到并学习。