What is the expected syntax for checking exception messages in MiniTest's assert_raises/must_raise?

RubyTddMinitestAssertion

Ruby Problem Overview


What is the expected syntax for checking exception messages in MiniTest's assert_raises/must_raise?

I'm trying to make an assertion something like the following, where "Foo" is the expected error message:

proc { bar.do_it }.must_raise RuntimeError.new("Foo")

Ruby Solutions


Solution 1 - Ruby

You can use the assert_raises assertion, or the must_raise expectation.

it "must raise" do
  assert_raises RuntimeError do 
    bar.do_it
  end
  ->     { bar.do_it }.must_raise RuntimeError
  lambda { bar.do_it }.must_raise RuntimeError
  proc   { bar.do_it }.must_raise RuntimeError
end

If you need to test something on the error object, you can get it from the assertion or expectation like so:

describe "testing the error object" do
  it "as an assertion" do
    err = assert_raises RuntimeError { bar.do_it }
    assert_match /Foo/, err.message
  end

  it "as an exception" do
    err = ->{ bar.do_it }.must_raise RuntimeError
    err.message.must_match /Foo/
  end
end

Solution 2 - Ruby

To assert exception:

assert_raises FooError do
  bar.do_it
end

To assert exception message:

As per API doc, assert_raises returns the exception matched so you can check the message, attributes, etc.

exception = assert_raises FooError do
  bar.do_it
end
assert_equal('Foo', exception.message)

Solution 3 - Ruby

Minitest does not provide (yet) you a way to check the actual exception message. But you could add a helper method that does it and extend ActiveSupport::TestCase class to use everywhere in your rails test suite, e.g.: in test_helper.rb

class ActiveSupport::TestCase
  def assert_raises_with_message(exception, msg, &block)
    block.call
  rescue exception => e
    assert_match msg, e.message
  else
    raise "Expected to raise #{exception} w/ message #{msg}, none raised"
  end
end

and use it in your tests like:

assert_raises_with_message RuntimeError, 'Foo' do
  code_that_raises_RuntimeError_with_Foo_message
end

Solution 4 - Ruby

To add some more recent developments, there have been some discussions on adding assert_raises_with_message to minitest in the past without much luck.

Currently, there is a promising pull request waiting to be merged. If and when it gets merged, we will be able to use assert_raises_with_message without having to define it ourselves.

In the meanwhile, there is this handy little gem named minitest-bonus-assertions which defines exactly that method, along with few others, so that you can use it out of the box. See the docs for more information.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkfitzpatrickView Question on Stackoverflow
Solution 1 - RubyblowmageView Answer on Stackoverflow
Solution 2 - RubyJing LiView Answer on Stackoverflow
Solution 3 - RubyDeveloperView Answer on Stackoverflow
Solution 4 - RubyKostas RousisView Answer on Stackoverflow