我正在做一些单元测试。其中一个使用在我的应用程序MyBigApp::Env
中设置的特定配置变量,如下所示:
{:country=>'uk', :another_hosts=>["192.168.99.105"]}
所以我用MyBigApp::Env.country
但是在我的单元测试中,我希望测试的country
变得有用。
使用rspec我已经看到了存根,但是无法使其正常工作-我出错的任何想法:
MyBigApp::Env.stub(:[]).with('country').and_return('gr')
也尝试过此操作(如上所示,已弃用):
allow(MyBigApp::Env).to receive('country').and_return('gr')
事实上,我也尝试过:
my_hash = {:uri=>nil}
allow(my_hash).to receive(:[]).with(:uri).and_return('Over written!')
p my_hash
并且没有更新-它只是返回{:uri=>nil}
作为一种解决方法,此刻,我必须将环境变量保存在before(each)
块中的临时变量中,然后将其返回到after(each)
中的原始变量。这对我来说真的很冒险。我在想,如果服务正在运行,并且有人在运行单元测试,那么在测试正在运行的那个小实例中,它可能会影响最终用户。
任何帮助将不胜感激。
谢谢
答案 0 :(得分:1)
是的,但是请记住,存根仅在触发/调用存根/模拟的方法时起作用
my_hash = {:uri=>nil}
allow(my_hash).to receive(:[]).with(:uri).and_return('Over written!')
p my_hash[:url] # it will be 'Over written!'
答案 1 :(得分:0)
这对我有用:
my_hash = {:uri=>nil}
allow(my_hash).to receive(:[]).with(:uri).and_return('Over written!')
expect(my_hash[:uri]).to eq "Over written!"
在示例测试用例中,您只是在调用p my_hash
,而实际上并没有调用[]
方法。
关于为什么MyBigApp::Env
不起作用,这实际上取决于它是什么类。可能无论使用哪种方法.country
都不会实际调用[]
。
真的,如果您致电MyBigApp::Env['country']
并存根MyBigApp::Env
以[]
接收'country'
,则应该起作用。
关于您是否希望通过测试来更改正在运行的应用程序的行为……这些是什么样的测试?针对实时生产应用程序运行单元测试非常奇怪。您如何看待它将改变您的生产应用程序的代码? Env
哈希仅存在于内存中吗?
无论如何,您永远不必担心测试会改变“最终用户”的体验。始终在完全隔离的环境中运行测试,这意味着不要使用相同的数据库。实际上,通常在每次测试后都会擦除测试数据库。
答案 2 :(得分:0)
只是想提出一个非存根的替代方案。例如:
def code_under_test
key = 'country'
# ... maybe lots of code
value = MyBigApp::Env[key] # deep inside some classes
# ... lots more code
"This is the #{value}"
end
MyBigApp::Env
在代码的深处进行了硬编码,对存根的需求表明该依赖关系以及OOP封装的好处都丧失了。
如果是这种情况,那就容易多了:
def code_under_test(config_vars = MyBigApp::Env)
"This is the #{config_vars['country']}"
end
it 'should return my country value' do
value = previous_code_under_test('country' => 'TEST VALUE')
expect(value).to eq("This is the TEST VALUE")
end
不需要存根,只需普通的旧方法调用即可。