Search code examples
ruby-on-railsrubyrspecrspec-rails

Double received unexpected message despite of stubbing


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!


Solution

  • 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.