范围
所有 rspec-mocks 构造都有每个示例的生命周期。消息期望在每个示例后进行验证。替身、方法存根、存根常量等都在每个示例后清理。这确保每个示例可以独立运行,并且可以按任何顺序运行。
在 `before(:example)` 钩子中设置替身、存根和消息期望完全没有问题,因为该钩子在示例范围内执行
before(:example) do
allow(MyClass).to receive(:foo)
end
由于 `before(:context)` 在任何单个示例范围之外运行,因此不支持在其中使用 rspec-mocks 功能。但是,您可以使用 `RSpec::Mocks.with_temporary_scope { }` 在 *任何* 任意上下文中(包括在 `before(:context)` 钩子中)创建临时范围。
无法在 `before(:context)` 钩子中创建替身
给定一个名为“before_context_spec.rb”的文件,其中包含
RSpec.describe "Creating a double in a before(:context) hook" do
before(:context) do
@dbl = double(:foo => 13)
end
it "fails before it gets to the examples" do
expect(@dbl.foo).to eq(13)
end
end
当我运行 `rspec before_context_spec.rb`
那么它应该失败,并显示
The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported.
使用 `with_temporary_scope` 在 `before(:context)` 钩子中创建和使用替身
给定一个名为“with_temporary_scope_spec.rb”的文件,其中包含
RSpec.describe "Creating a double in a before(:context) hook" do
before(:context) do
RSpec::Mocks.with_temporary_scope do
dbl = double(:foo => 13)
@result = dbl.foo
end
end
it "allows a double to be created and used from within a with_temporary_scope block" do
expect(@result).to eq(13)
end
end
当我运行 `rspec with_temporary_scope_spec.rb`
那么示例应该全部通过。
替身不能在另一个示例中重复使用
给定一个名为“leak_test_double_spec.rb”的文件,其中包含
class Account
class << self
attr_accessor :logger
end
def initialize
@balance = 0
end
attr_reader :balance
def credit(amount)
@balance += amount
self.class.logger.log("Credited $#{amount}")
end
end
RSpec.describe Account do
it "logs each credit" do
Account.logger = logger = double("Logger")
expect(logger).to receive(:log).with("Credited $15")
account = Account.new
account.credit(15)
end
it "keeps track of the balance" do
account = Account.new
expect { account.credit(10) }.to change { account.balance }.by(10)
end
end
当我运行 `rspec leak_test_double_spec.rb`
那么它应该失败,并显示以下输出
2 个示例,1 个失败 |
1) 账户跟踪余额 |
失败/错误: self.class.logger.log(“Credited $#{amount}”) |
# |