Skip to content
Polly Sileo edited this page Jun 6, 2015 · 1 revision
class AboutExceptions < Neo::Koan

  class MySpecialError < RuntimeError
  end

  def test_exceptions_inherit_from_Exception
    assert_equal RuntimeError, MySpecialError.ancestors[1]
    assert_equal StandardError, MySpecialError.ancestors[2]
    assert_equal Exception, MySpecialError.ancestors[3]
    assert_equal Object, MySpecialError.ancestors[4]
  end

All exceptions inherit from Exception Class this new error created inherits from RuntimeError which inherits from StandardError, which inherits from Exception, and Object (as everything in ruby inherits from Object) so exceptions will inherit from all these exceptions.

  def test_rescue_clause
    result = nil
    begin
      fail "Oops"
    rescue StandardError => ex
      result = :exception_handled
    end

    assert_equal :exception_handled, result

    assert_equal true, ex.is_a?(StandardError), "Should be a Standard Error"
    assert_equal true, ex.is_a?(RuntimeError),  "Should be a Runtime Error"

    assert RuntimeError.ancestors.include?(StandardError),
      "RuntimeError is a subclass of StandardError"

    assert_equal "Oops", ex.message
  end

result is defined as being = to :exception_handled so the first test is checking that it has been defined as such. rescue assigns a rescue clause so here rescue is assigning that a StandardError has occured and the rescue clause is ex. So when we test it ex.is_a? will return true for StandardError because we have assigned it in the rescue and it will also return true for RuntimeError because StandardError inherits from RuntimeError. "Oops" is the message that is assigned to rescue so ex.message will return "Ooops"

  def test_raising_a_particular_error
    result = nil
    begin
      # 'raise' and 'fail' are synonyms
      raise MySpecialError, "My Message"
    rescue MySpecialError => ex
      result = :exception_handled
    end

    assert_equal :exception_handled, result
    assert_equal "My Message", ex.message
  end

:exception_handled is stored as the result when it gets to the end of the function. "My message" is stored as the message for MySpectialError and does not get overridden because when rescue runs nothing gets touch after that it exits out of the method.

  def test_ensure_clause
    result = nil
    begin
      fail "Oops"
    rescue StandardError
      # no code here
    ensure
      result = :always_run
    end

    assert_equal :always_run, result
  end

Ensure will run even if it's after a a rescue. so in this case "result" gets overridden with the new value :always_run.

  # Sometimes, we must know about the unknown
  def test_asserting_an_error_is_raised
    assert_raise(Exception) do
      raise MySpecialError.new("New instances can be raised directly.")
    end
  end
end

I'm not sure what is happening here. There is an iteration over assert_raise(Exception).