Rspec - 是否可以存根哈希

问题描述 投票:0回答:3

我正在进行一些单元测试。其中一个使用我的应用程序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)中的原始值。这对我来说真的很危险。我在想,假设服务正在运行,有人运行单元测试,它可能会影响测试运行的那个小实例中的最终用户。

任何帮助,将不胜感激。

谢谢

ruby rspec
3个回答
1
投票

是的可能,但请记住,只有当您触发/调用存根/模拟的方法时,存根才有效

after(each)

0
投票

这对我有用:

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'哈希只是生活在记忆中吗?

无论如何,您永远不必担心您的测试会改变“最终用户”的体验。始终在完全隔离的环境中运行测试,这意味着不要使用相同的数据库。实际上,通常在每次测试后擦除测试数据库。


0
投票

只是想建议一个非顽固的替代方案。例如:

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

不需要存根,只需要简单的旧方法调用。

© www.soinside.com 2019 - 2024. All rights reserved.