I am working on a Rails application. I am trying to stub a method globally.
What I am doing is to stub it inside the RSpec configuration, on a before(:suite)
block as follows:
RSpec.configure do |config|
config.before(:suite) do
allow_any_instance_of(MyModel).to receive(:my_method).and_return(false)
end
end
However, starting the test fails with the following error:
in `method_missing': undefined method `allow_any_instance_of' for #<RSpec::Core::ExampleGroup:0x00000008d6be08> (NoMethodError)
Any clue? How should I stub a method globally using RSpec?
P.
I recently ran into a case where I needed to stub something in a
before(:all)
orbefore(:context)
block, and found the solutions here to not work for my use case.RSpec docs on before() & after() hooks says that it's not supported:
Problem
I was making a gem for writing a binary file format which contained at unix epoch timestamp within it's binary header. I wanted to write RSpec tests to check the output file header for correctness, and compare it to a test fixture binary reference file. In order to create fast tests I needed to write the file out once before all the example group blocks would run. In order to check the timestamp against the reference file, I needed to force
Time.now()
to return a constant value. This led me down the path of trying to stubTime.now
to return my target value.However, since
rspec/mocks
did not support stubbing within abefore(:all)
orbefore(:context)
block it didn't work. Writing the filebefore(:each)
caused other strange problems.Luckily, I stumbled across issue #240 of rspec-mocks which had the solution!
Solution
Since January 9th 2014 (rspec-mocks PR #519) RSpec now contains a method to work around this:
RSpec::Mocks.with_temporary_scope
Example
You may use the following to stub a method 'do_this' of class 'Xyz' :
This stubs the output to - ':this_is_your_stubbed_output' from wherever this function is invoked.
You may use the above piece of code in before(:each) block to make this applicable for all your spec examples.
Do not stub methods in
before(:suite)
because stubs are cleared after each example, as stated in the rspec-mocks README:I think that's why
allow_any_instance_of
is not available inbefore(:suite)
block, but is available inbefore(:each)
block.If the method is still missing, maybe you configured rspec-mocks to only allow
:should
syntax.allow_any_instance_of
was introduced in RSpec 2.14 with all the new:expect
syntax for message expectations.Ensure that this syntax is enabled by inspecting the value of
RSpec::Mocks.configuration.syntax
. It is an array of the available syntaxes in rspec-mocks. The available syntaxes are:expect
and:should
.Once configured properly, you should be able to use
allow_any_instance_of
.If you want a particular method to behave a certain way for your entire test suite, there's no reason to even deal with RSpec's stubs. Instead, you can simply (re)define the method to behave how you want in your test environment:
This could go in
spec/spec_helper.rb
or a similar file.It probably is a context / initialization issue. Doing it in
config.before(:each)
should solve your problem.What version of RSpec are you using? I believe
allow_any_instance_of
was introduced in RSpec 2.14. For earlier versions, you can use: