sdawes
sdawes

Reputation: 661

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

Upvotes: 0

Views: 1609

Answers (1)

spickermann
spickermann

Reputation: 106802

You haven't defined a already_landed? method. That means calling already_landed? would always raise a NoMethodError: undefined method 'already_landed?' exception, but never the expected Plane can not land... exception. And therefore your expectation does not pass.

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

Upvotes: 1

Related Questions