【发布时间】:2015-11-26 07:04:37
【问题描述】:
我正在开发一个描述生成器功能,该功能将查看对象属性并通过从已设置的各种语言环境(多种语言)中提取字符串来填充描述。
我有以下代码
module Rooms
class DescriptionGenerator
attr_reader :room, :locale
def initialize(room, locale="en")
@room = room
@locale = locale
end
private
def t(key, options={})
I18n.t("rooms.description_generator.#{key}", options.merge({ locale: locale }))
end
def wifi
t("wifi", room_type: room.room_type.type).values.sample if room.wifi
end
然后我有以下测试:
describe "#wifi" do
let!(:room_with_wifi) { create(:room, :visible, wifi: true) }
let!(:room) { create(:room) }
#This one is failing
it "returns wifi sentence if room has wifi" do
sentence = I18n.t('rooms.description_generator.wifi', room_type: room_with_wifi.room_type.type).values.sample
expect(Rooms::DescriptionGenerator.new(room_with_wifi,"en").send(:wifi)).to eq (sentence)
end
it "returns nil if room does not have wifi" do
expect(Rooms::DescriptionGenerator.new(room,"en").send(:wifi)).to eq nil
end
end
我的问题是“在使用样本的情况下,最好的测试方法是什么?”
我最初的解决方案(我很确定不推荐)是添加:
class DescriptionGenerator
def sample(arr)
if Rails.env.test?
arr.values.first
else
arr.sample.values
end
end
end
这“强制”RSpec 将采用我的语言环境中的第一个选项,如下所示:
three_positive_reviews:
a: "This is not so great"
b: "This %{string_for_interpolation} is great."
c: "This is bad"
这一切都过去了,直到我添加了一个要插入到测试中使用的第一个 (a) 的字符串,并意识到在 i18n gem 中不支持数组内的插值 (Interpolation in I18n array)。
所以我重构为:
def t(key, options={})
value = I18n.t("rooms.description_generator.#{key}")
key = "#{key}.#{sample(value.keys)}" if value.is_a?(Hash)
I18n.t("rooms.description_generator.#{key}", options.merge({ locale: locale }))
end
def sample(keys)
if Rails.env.test?
keys.first
else
keys.sample
end
end
这现在通过了我的测试套件 - 但是在详细研究了这个之后想寻求更优化的解决方案以及我如何更合适地进行测试(也许通过存根样本??)没有这条线
if Rails.env.test?
【问题讨论】:
标签: ruby-on-rails ruby rspec internationalization