Reputation: 2415
I need to test the passed argument type is an integer. Here is my test spec:
require 'ball_spin'
RSpec.describe BallSpin do
describe '#create_ball_spin' do
subject(:ball_spin) { BallSpin.new }
it 'should accept an integer argument' do
expect(ball_spin).to receive(:create_ball_spin).with(an_instance_of(Integer))
ball_spin.create_ball_spin(5)
end
end
end
My code:
class BallSpin
def create_ball_spin n
"Created a ball spin #{n} times" if n.is_a? Integer
end
end
Thanks in advance
UPDATE:
Apologize for using old RSpec syntax, below I updated my code to use the latest one:
it 'should accept an integer argument' do
expect(ball_spin).to receive(:create_ball_spin).with(an_instance_of(Integer))
ball_spin.create_ball_spin(5)
end
Upvotes: 4
Views: 7731
Reputation: 515
I think the reason is that 5 is an instance of Fixnum and not Integer:
2.2.1 :005 > 5.instance_of?(Fixnum)
=> true
2.2.1 :006 > 5.instance_of?(Integer)
=> false
UPDATE: Ok, I've tried your code and the problem is Integer instead of Fixnum. Here is the correct assertion:
RSpec.describe BallSpin do
describe '#create_ball_spin' do
subject(:ball_spin) { BallSpin.new }
it 'should accept an integer argument' do
expect(ball_spin).to receive(:create_ball_spin).with(an_instance_of(Fixnum))
ball_spin.create_ball_spin(5)
end
end
end
Upvotes: 2
Reputation: 106972
The use case of the receive
matcher is to spec that a method is called by someone. But it is worth noting that the matcher itself doesn't call that method nor it tests if the method exists or if the list of possible arguments matches a given pattern.
It seems like your code doesn't call that method at all. A simple test that should pass might look like this:
subject(:ball_spin) { BallSpin.new }
it 'is called with an integer argument' do
ball_spin.should_receive(:create_ball_spin).with(an_instance_of(Integer))
ball_spin.create_ball_spin(5) # method called
end
it 'is not called' do
ball_spin.should_not_receive(:create_ball_spin)
# method not called
end
See section Argument Matcher.
Btw you use the old RSpec syntax and might want to consider updating your test suite to the new expect
syntax.
Upvotes: 1
Reputation: 2860
You may add a block to receive
to check the method params:
expect(ball_spin).to receive(:create_ball_spin) do |arg|
expect(arg.size).to be_a Integer
end
You may find details in Arbitrary Handling
section of rspec-mocks
documentation.
UPDATE: Also you may use the same approach with should
syntax:
ball_spin.should_receive(:create_ball_spin) do |arg|
arg.should be_a Integer
end
Upvotes: 11