2017-08-18 8 views
1

私はRuby 2.3.4とrspec 3.6.0を使用しています。rspecでrandをスタブする方法は?

rand(10000..99999)を使用するオブジェクトのテストを作成しています。私はrandの文書を見つけることができません。私はKernelObject、およびRandom(下記参照)をスタブしようとしましたが、私の試みではrandがスタブされていませんでした。

allow(Kernel).to receive(rand).and_return(12345) 
allow(Object).to receive(rand).and_return(12345) 
allow(Random).to receive(rand).and_return(12345) 

助けてください。

答えて

5

randは実際にKernelモジュールに実装されています。ただし、コード内でメソッドを呼び出すとき、メソッド受信者は実際には独自のオブジェクトです。

次のクラスとしますmy_random.randomを呼び出すとき、これはselfされているオブジェクトであるため、受信機(すなわち、メソッドが上で呼び出されたオブジェクト)rand方法の再度my_randomインスタンス

class MyRandom 
    def random 
    rand(10000..99999) 
    end 
end 

my_random = MyRandom.new 
my_random.random 
# => 56789 

MyRandom#random方法の場合。

これをテストするとき、あなたはこのスタブは、このインスタンスでrand方法することができます:

describe MyRandom do 
    let(:subject) { described_class.new } 

    describe '#random' do 
    it 'calls rand' do 
     expect(subject).to receive(:rand).and_return(12345) 
     expect(subject.random).to eq 12345 
    end 
    end 
end 
+0

興味深い、私は考えルビーは 'それを呼び出してオブジェクトにそれ自身で呼び出さrand'が割り当てられませんでした。これはうまくいって、ありがとう! – theartofbeing

+0

これはすべてのモジュールで同じです。モジュールをクラスに含めると、メソッドはクラスインスタンスで呼び出されます。 'Kernel'はここでも違いはありません。 'Kernel'モジュールはすべてのオブジェクトにデフォルトで含まれているので、そのメソッドはどこでも呼び出すことができるという点で「特別な」ことだけです。それはまだ普通のモジュールなので、他のメソッドと同じ方法でクラスごとのメソッドを上書きすることができます(そうしなければならないが)。 –

関連する問題