Reputation: 179
Double received unexpected message
failure/error is reported when attempting to run the following spec:
MyKlass
does something
does something again (FAILED - 1)
Failures:
1) MyKlass does something again
Failure/Error: MyKlass.do_something
Double "OtherKlass" received unexpected message :closed? with (no args)
# ./lib/my_klass.rb:5:in `do_something'
# ./spec/my_klass_spec.rb:17:in `block (2 levels) in <top (required)>'
Finished in 2.05 seconds
2 examples, 1 failure
Failed examples:
rspec ./spec/my_klass_spec.rb:16 # MyKlass does something again
Here is a minimal example to easily reproduce this issue...
Spec file spec/my_klass_spec.rb
:
1 require "spec_helper"
2
3 class OtherKlass; end
4
5 describe MyKlass do
6 let(:objekt) { double("OtherKlass", closed?: "NOT REALLY") }
7
8 before :each do
9 OtherKlass.stub(:get_objekt).and_return(objekt)
10 end
11
12 it "does something" do
13 MyKlass.do_something
14 end
15
16 it "does something again" do
17 MyKlass.do_something
18 MyKlass.do_something
19 end
20 end
And code lib/my_klass.rb
:
1 class MyKlass
2 @@klass_var = nil
3
4 def self.do_something
5 if @@klass_var.blank? || @@klass_var.closed?
6 @@klass_var ||= OtherKlass.get_objekt
7 end
8 end
9 end
I cannot understand why closed?
is reported to be an unexpected message, when it is stubbed in my spec file on line 6.
Many thanks in advance for your assistance!
Upvotes: 2
Views: 10591
Reputation: 179
Setting a class variable explicitly before each test solves the problem:
before(:each) do
MyKlass.class_variable_set :@@klass_var, nil
end
Probably somebody can find a better solution, however this one has worked for me.
Upvotes: 0
Reputation: 54684
In RSpec 3, you can use class_double
, which allows you to create a double of a class. Combined with as_stubbed_const
, you can replace the original implementation of a class:
RSpec.describe MyKlass do
let(:objekt) do
double(OtherKlass, closed?: 'NOT REALLY')
end
before do
class_double(OtherKlass, get_objekt: objekt).as_stubbed_const
end
it 'does something' do
MyKlass.do_something
end
end
In Rspec 2 the following should work:
RSpec.describe MyKlass do
let(:objekt) do
double('OtherKlass', closed?: 'NOT REALLY')
end
before do
fake_klass = Class.new
fake_klass.stub(:get_objekt) { objekt }
stub_const('OtherKlass', fake_klass)
end
it 'does something' do
MyKlass.do_something
end
end
Upvotes: 1