我正在进行一些单元测试。其中一个使用我的应用程序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
并且没有更新 - 它刚刚返回qazxsw poi
作为一种解决方法,目前我必须将env var保存在{:uri=>nil}
块中的temp var中,然后将其返回到before(each)
中的原始值。这对我来说真的很危险。我在想,假设服务正在运行,有人运行单元测试,它可能会影响测试运行的那个小实例中的最终用户。
任何帮助,将不胜感激。
谢谢
是的可能,但请记住,只有当您触发/调用存根/模拟的方法时,存根才有效
after(each)
这对我有用:
my_hash = {:uri=>nil}
allow(my_hash).to receive(:[]).with(:uri).and_return('Over written!')
p my_hash[:url] # it will be 'Over written!'
在您的示例测试用例中,您只是调用实际上不调用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
。
真的,如果你打电话给[]
和stub MyBigApp::Env['country']
用MyBigApp::Env
接收[]
,它应该可行。
关于从测试中改变正在运行的应用程序行为的问题......这些是什么样的测试?!针对实时生产应用程序运行单元测试将非常奇怪。你怎么想象它会改变你的生产应用程序的代码? 'country'
哈希只是生活在记忆中吗?
无论如何,您永远不必担心您的测试会改变“最终用户”的体验。始终在完全隔离的环境中运行测试,这意味着不要使用相同的数据库。实际上,通常在每次测试后擦除测试数据库。
只是想建议一个非顽固的替代方案。例如:
Env
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
在代码深处是硬编码的,并且对存根的需求表明依赖性和OOP封装的好处都会丢失。
如果是这样的话会更容易:
MyBigApp::Env
不需要存根,只需要简单的旧方法调用。