2017-08-18 33 views
1

我使用Ruby 2.3.4和rspec 3.6.0。如何在rspec中存根rand?

我正在爲使用rand(10000..99999)的對象編寫測試。我找不到rand上的任何文檔來查看它是哪個對象的一部分。我試圖剔除Kernel,ObjectRandom(見下文),但我的任何嘗試都沒有導致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模塊中實現。但是,在代碼中調用方法時,方法接收器實際上是您自己的對象。

假設下面的類:

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

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

當調用my_random.random,所述接收器(即在其上調用方法上的對象)的rand方法的又是my_random實例,因爲這是被self對象在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」模塊,從而允許在任何地方調用其方法。因爲它仍然是一個普通的模塊,所以你可以像使用其他方法一樣覆蓋每個類的方法(儘管你應該小心這樣做)。 –