rspec是否Rails.env.production?返回字符串如何实现?

时间:2018-11-06 13:01:37

标签: ruby-on-rails rspec

它不起作用。您能帮我为案例编写正确的测试吗?非常感谢。  #model.rb

def driver_iq_api
  if Rails.env.production?
    'https://admin.sss/xmlpost.cfm'
  else
    'https://eeem/ws/xmlpost.cfm'
  end
end

model_spec.rb

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

3 个答案:

答案 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所说的话,这种方法对于实际执行写数据库等操作的方法很危险。我只会将它用于示例中的方法类型...根据环境返回资源名称,布尔值等。如果您对平台敏感的代码被深深地埋在一个方法中,并且无法孤立地进行测试,则将其从大型方法中重构为一个原子方法,可以轻松地对其进行测试(并模拟!)。