sdawes sdawes - 6 months ago 60
Ruby Question

RSpec Raising an Exception - expected exception, but nothing was raised response?

I am doing a coding challenge and am trying to make one RSpec test pass, however I am unsure why my code is not passing. The error I am getting after running RSpec is:

1) Plane#land raises an error if already landed
Failure/Error: expect { plane.land }.to raise_error 'Plane can not land as it is already on the ground'
expected Exception with "Plane can not land as it is already on the ground" but nothing was raised
# ./spec/plane_spec.rb:22:in `block (3 levels) in '


the RSpec test code is:

describe Plane do

let(:plane) { Plane.new }

describe '#land' do
it 'raises an error if already landed' do
plane.land
expect { plane.land }.to raise_error 'Plane can not land as it is already on the ground'
end
end


end

And my main code is:

class Plane

def initialize
@in_air = true
end

def land
fail "Plane can not land as it is already on the ground" if already_landed?
@in_air = false
end
end


I have tried substituting back plane for Plane.new and tried using
raise
instead of
fail
and I have double checked, but I can not see why it is not working.

Many thanks

Answer

You haven't defined a already_landed? method. That means already_landed will always return nil and if already_landed? will always return false and the exception will never been raised.

Just add the already_landed? method to your model:

class Plane
  def initialize
    @in_air = true
  end

  def land
    fail "Plane can not land as it is already on the ground" if already_landed?
    @in_air = false
  end

  def already_landed?
    !@in_air
  end
end

Btw: Does it makes sense that a newly created plane will already be in_air? I would expect in_air to be false on initialization and that you need to start first. I would change that behavior:

class Plane
  attr_accessor :flying

  def fly
    # no exception here, I assume it is save to continue flying, when already in air
    self.flying = true
  end

  def land
    fail 'Plane can not land as it is already on the ground' if landed
    self.flying = false
  end

  def landed
    !flying
  end
end

plane = Plane.new
plane.land
#=> RuntimeError: Plane can not land as it is already on the ground