Joe Joe - 3 months ago 13
Ruby Question

Prevent ArgumentError when using RSpec Doubles

I am currently trying to raise an error with the following code:

class NasaController
attr_reader :plateau, :current_rover

def initialize(plateau:)
@plateau = plateau
@current_rover = []
end

def link_to_rover(robotic_rover)
raise ArgumentError, "#{robotic_rover.class}" unless robotic_rover.is_a? RoboticRover
@current_rover = robotic_rover
end
end


and it works! Great! But........

My tests are:

describe NasaController do
subject(:controller) { described_class.new(plateau: plateau) }

let(:robotic_rover) do
double(:robotic_rover, #some_methods...)
end

let(:plateau) { double(:plateau, rover_landed: landed_rover) }

describe 'interacting with a rover' do
context 'when a RoboticRover is used' do
before { controller.link_to_rover(robotic_rover) }

it 'can create a link' do
expect(controller.current_rover).to eq robotic_rover
end

context 'when something other than a RoboticRover is used' do
it 'raises an error at #link_to_rover' do
expect { controller.link_to_rover(plateau) }.to raise_error 'Error!'
end
end
end
end


Which leads to my second test passing because
controller.link_to_rover(plateau)
does not link a RoboticRover.

But, my first fails because
controller.link_to_rover(robotic_rover)
is also not a RoboticRover, it is a double of a RoboticRover. Does anyone have any guidance on getting around this issue?

Answer

You need to allow plateau to receive is_a?, with an argument of RoboticRover, and have it return true. Try adding the following to the failing test:

allow(plateau).to receive(:is_a?).with(RoboticRover).and_return(true)

See here for more information.