privateのクラスメソッドをスタブにすると、そのメソッドをSpec上で呼び出すときに、undefined method になる


原因は不明

本体

class Test
  def self.foo 
    var + 'bbb'
  end
  
  def self.var
    'aaa'
  end
  private_class_method :var
end

テスト

require 'test.rb'

describe Test do
  it 'foo' do
    
    #Test.should_receive(:var).and_return('ccc')
    Test.stub!(:var).and_return('ccc')
    Test.foo.should == 'cccbbb'
  end
  
  it 'var' do
    Test.send(:var).should == 'aaa' 
  end
end

実行結果

spec -c test_spec.rb
.F

1)
NoMethodError in 'Test var'
undefined method `var' for Test:Class
./test_spec.rb:12:in `send'
./test_spec.rb:12:

Finished in 0.430245 seconds

2 examples, 1 failure

対策


とりあえず、public にしたら大丈夫だった
なんでだろ???

追記


Object - Rubyリファレンスマニュアル
http://www.ruby-lang.org/ja/man/html/Object.html#send

ruby 1.9 feature: 呼び出し制限がsend, __send__にも影響するようになり、
レシーバを指定した呼び出しではprivateメソッドを呼び出せなくなりました。 
privateメソッドを呼び出す必要がある場合はinstance_evalを使用してください。


1.9 から private メソッドを呼べなくなるらしいので、それはそれで注意

追記


ソースの内側まで突っ込んだ話


KoshigoeBLOG: RSpec の stub! とプライベートメソッドの話
http://blog.koshigoe.jp/archives/2009/12/rspec_stub.html