mar*_*rgo 2 singleton rspec ruby-on-rails-4
我有一个单例类,许多其他类和控制器可以访问该类来确定行为。如何在测试中设置单例值以便测试行为。下面的示例代码中,Setting 是一个 Singleton 类,它由数据库支持并存储应用程序范围的设置,并且管理员可以更改这些设置。Floodgate 是访问设置的类。
class Setting
def instance
@setting ||= new
end
end
class Floodgate
def self.whitelist
Setting.instance.flood_gate_whitelist
end
end
Run Code Online (Sandbox Code Playgroud)
以下是 Floodgate 的一些测试,需要访问设置数据库值。
describe Floodgate do
let(:setting) { Class.create(Setting).instance }
describe ".whitelist" do
it "returns a list of values on the Settings floodgate whitelist" do
expect(Floodgate.whitelist).to eq 'google'
end
end
describe ".allow_traffic_source?" do
it "returns true if traffic source is on the white list" do
expect(Floodgate.allow_traffic_source?('google')).to eq true
end
it "returns false if traffic source is not on the white list" do
expect(Floodgate.allow_traffic_source?('facebook')).to eq false
end
end
Run Code Online (Sandbox Code Playgroud)
上面的第一个和第二个测试失败,因为Setting.flood_gate_whitelist为nil。在 Floodgate 测试中,我如何设置它以便它持续存在,atm d/b 中没有记录。我尝试将其显式设置如下,当我使用 create 时,错误响应是未定义的方法“create”。
let(:setting) { Class.new(Setting, flood_gate_whitelist: 'google').instance }
Run Code Online (Sandbox Code Playgroud)
存根被调用的消息链。在你的情况下,一个例子是:
before do
allow(Setting).
to receive_message_chain("instance.flood_gate_whitelist").
and_return("google")
end
Run Code Online (Sandbox Code Playgroud)
现在Setting.instance.flood_gate_whitelist代码中的任何位置都将返回"google".
或者,您可以像这样对实例方法进行存根Setting:
before do
allow_any_instance_of(Setting).
to receive(:flood_gate_whitelist).
and_return("google")
end
Run Code Online (Sandbox Code Playgroud)
如果您确定实例化Setting正确,请选择后者。
顺便说一句,与配置相关的变量理想地应放入一个*.yml文件中(例如database.yml,要使用哪个数据库),该文件将根据当前项目环境具有不同的值(在许多情况下,这将消除对存根方法的需要)。
| 归档时间: |
|
| 查看次数: |
1352 次 |
| 最近记录: |