它不起作用。您能帮我为案例编写正确的测试吗?非常感谢。 #model.rb
def driver_iq_api
if Rails.env.production?
'https://admin.sss/xmlpost.cfm'
else
'https://eeem/ws/xmlpost.cfm'
end
end
describe 'private methods' do
context '.driver_iq_api' do
it 'production true' do
allow(Rails.env).to receive(:production?) {true}.and_return('https://admin.sss/xmlpost.cfm')
end
it 'production false' do
allow(Rails.env).to receive(:production?) {false}.and_return('https://eeem/ws/xmlpost.cfm')
end
end
end
答案 0 :(得分:1)
在测试中将Rails.env
设置为test
以外的其他东西是一个坏主意。在这种情况下,尽管您可能会“摆脱它”,但它通常会引起各种奇怪的副作用,例如将数据写入非测试数据库。
此外,看来您正在为私有方法编写单元测试,这通常是一个坏主意。您通常应该只测试类的公共接口。
如上所述,理想情况下,这种配置应位于配置文件中,例如application.yml
。
other answer已经显示了您如何可以终止行为,但作为另一种选择,您可以考虑将环境作为方法依赖项注入:
def driver_iq_api(env: Rails.env)
if env.production?
'https://admin.sss/xmlpost.cfm'
else
'https://eeem/ws/xmlpost.cfm'
end
end
describe '#driver_iq_api' do
it 'production env' do
expect(model.driver_iq_api(env: 'production'.inquiry)).to eq 'https://admin.sss/xmlpost.cfm'
end
it 'test env' do
expect(model.driver_iq_api(env: 'test'.inquiry)).to eq 'https://eeem/ws/xmlpost.cfm'
end
end
请注意,例如,'test'.inquiry
返回一个ActiveSupport::StringInquirer
实例-与调用Rails.env
的行为相同。
...但是要重申我的初衷,我根本不会去测试这种方法。
答案 1 :(得分:0)
我同意您应该将其放入配置中,因为它是静态的,但要回答您的问题:
it "when production" do
allow(Rails.env).to receive(:production?).and_return(true)
expect(my_class.send(:driver_iq_api)).to eq('https://admin.sss/xmlpost.cfm')
end
答案 2 :(得分:0)
对于您的测试,我对您使用的receive...{block}
语法不熟悉,并且我严重怀疑是否要测试您认为正在测试的内容。
这是一个测试套件,其测试更加简洁,任何人都非常容易阅读:
describe '.driver_iq_api' do
subject { MyModel.driver_iq_api }
context 'when in production' do
allow(Rails.env).to receive(:production?).and_return(true)
it { is_expected.to eq 'https://admin.sss/xmlpost.cfm' }
end
context 'when not in production' do
it { is_expected.to eq 'https://eeem/ws/xmlpost.cfm' }
end
end
为了强化@Tom Lord所说的话,这种方法对于实际执行写数据库等操作的方法很危险。我只会将它用于示例中的方法类型...根据环境返回资源名称,布尔值等。如果您对平台敏感的代码被深深地埋在一个方法中,并且无法孤立地进行测试,则将其从大型方法中重构为一个原子方法,可以轻松地对其进行测试(并模拟!)。