[英]rspec if Rails.env.production? return string how to implemented it?
And it does not work.它不起作用。 Can you help me how to write the right test for its case?
你能帮我如何为它的案例编写正确的测试吗? Thanks very much.
非常感谢。 #model.rb
#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
Setting Rails.env
to something other than test
, inside a test, is a bad idea.在
test
Rails.env
设置为test
以外的内容是一个坏主意。 Whilst you may "get away with it" in this case, it could cause all sorts of weird side-effects in general, such as writing data to a non-test database.虽然在这种情况下您可能会“侥幸逃脱”,但通常它可能会导致各种奇怪的副作用,例如将数据写入非测试数据库。
In addition , it seems you're writing unit tests for private methods, which is typically a bad idea.此外,您似乎正在为私有方法编写单元测试,这通常是一个坏主意。 You should only normally test the public interface of a class.
您通常应该只测试类的公共接口。
As stated above, this sort of config should ideally live in a configuration file, such as eg application.yml
.如上所述,理想情况下,这种配置应该存在于配置文件中,例如
application.yml
。
The other answer already shows how you could stub the behaviour, but as yet another alternative, you could consider injecting the environment as a method dependency:在其他的答案已经展示了如何存根的行为,但作为另一种选择,你可以考虑注射环境作为一种方法依赖:
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
Note that for example, 'test'.inquiry
returns a ActiveSupport::StringInquirer
instance - which is the same behaviour as calling Rails.env
.请注意,例如,
'test'.inquiry
返回一个ActiveSupport::StringInquirer
实例 - 这与调用Rails.env
行为相同。
...But to reiterate my original point, I wouldn't bother testing this method at all. ...但重申我原来的观点,我根本不会费心测试这种方法。
I agree you should pull this out into config since it is static, but to answer your question:我同意您应该将其提取到配置中,因为它是静态的,但要回答您的问题:
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
As for you test, I'm not familiar with the receive...{block}
syntax you use, and I doubt seriously that tests what you think it is testing.至于你的测试,我不熟悉你使用的
receive...{block}
语法,我严重怀疑测试你认为它正在测试的内容。
Here is a test suite that tests much more succinctly, and is super easy for anyone to read:这是一个测试套件,它的测试更加简洁,任何人都非常容易阅读:
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
And to reinforce what @Tom Lord said, this approach is dangerous for methods that actually do things like write to databases and such.为了加强@Tom Lord 所说的,这种方法对于实际执行诸如写入数据库等操作的方法是危险的。 I'd use this only for the type of method you have in your example...returning a resource name, boolean, etc. based on env.
我只会将它用于示例中的方法类型……基于 env 返回资源名称、布尔值等。 If your platform-sensitive code is buried deep in a method and can't be tested in isolation, then refactor it out of the big method into an atomic method that can easily be tested (and mocked!).
如果您的平台敏感代码深埋在方法中并且无法单独测试,那么将其从大方法中重构为易于测试(和模拟!)的原子方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.