Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stub rand in rspec?

Tags:

ruby

rspec

I'm using Ruby 2.3.4 and rspec 3.6.0.

I'm writing a test for an object that uses rand(10000..99999). I can't find any docs on rand to see what object it's a part of. I tried stubbing Kernel, Object, and Random (see below) but none of my attempts resulted in rand being stubbed for the object.

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

Any help is appreciated.

like image 534
theartofbeing Avatar asked Aug 18 '17 16:08

theartofbeing


1 Answers

rand is indeed implemented in the Kernel module. However, when calling the method inside your code, the method receiver is actually your own object.

Assume the following class:

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

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

When calling my_random.random, the receiver (i.e. the object on which the method is called on) of the rand method is again the my_random instance since this is the object being self in the MyRandom#random method.

When testing this, you can this stub the rand method on this instance:

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
like image 189
Holger Just Avatar answered Sep 24 '22 23:09

Holger Just