To add a collaborator to this project you will need to use the Relish gem to add the collaborator via a terminal command. Soon you'll be able to also add collaborators here!
More about adding a collaboratorScope
All rspec-mocks constructs have a per-example lifecycle. Message expectations are verified
after each example. Doubles, method stubs, stubbed constants, etc. are all cleaned up after
each example. This ensures that each example can be run in isolation, and in any order.
It is perfectly fine to set up doubles, stubs, and message expectations in a
before(:example)
hook, as that hook is executed in the scope of the example:
before(:example) do
allow(MyClass).to receive(:foo)
end
Since before(:context)
runs outside the scope of any individual example, usage of
rspec-mocks features is not supported there. You can, however, create a temporary scope in
any arbitrary context, including in a before(:context)
hook, using
RSpec::Mocks.with_temporary_scope { }
.
- Scenarios
-
- Cannot create doubles in a `before(:context)` hook
- Use `with_temporary_scope` to create and use a double in a `before(:context)` hook
- Doubles cannot be reused in another example
- Cannot create doubles in a `before(:context)` hook
-
- Given
-
a file named "before_context_spec.rb" with:
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
- When
-
I run
rspec before_context_spec.rb
- Then
-
it should fail with:
The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported.
- Use `with_temporary_scope` to create and use a double in a `before(:context)` hook
-
- Given
-
a file named "with_temporary_scope_spec.rb" with:
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
- When
-
I run
rspec with_temporary_scope_spec.rb
- Then
- the examples should all pass
- Doubles cannot be reused in another example
-
- Given
-
a file named "leak_test_double_spec.rb" with:
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
- When
-
I run
rspec leak_test_double_spec.rb
- Then
-
it should fail with the following output:
2 examples, 1 failure 1) Account keeps track of the balance Failure/Error: self.class.logger.log("Credited $#{amount}") #<Double "Logger"> was originally created in one example but has leaked into another example and can no longer be used.
Last published almost 3 years ago by Jon Rowe.