Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test that invalid arguments raise an ArgumentError exception using RSpec?

Tags:

ruby

rspec

I'm writing a RubyGem that can raise an ArgumentError if the arguments supplied to its single method are invalid. How can I write a test for this using RSpec?

The example below shows the sort of implementation I have in mind. The bar method expects a single boolean argument (:baz), the type of which is checked to make sure that it actually is a boolean:

module Foo
  def self.bar(options = {})
    baz = options.fetch(:baz, true)
    validate_arguments(baz)
  end

  private
  def self.validate_arguments(baz)
    raise(ArgumentError, ":baz must be a boolean") unless valid_baz?(baz)
  end

  def self.valid_baz?(baz)
    baz.is_a?(TrueClass) || baz.is_a?(FalseClass)
  end
end
like image 660
John Topley Avatar asked May 16 '10 09:05

John Topley


3 Answers

I use something similar to what JHurra posted:

it "should raise ArgumentError for arguments that are not boolean" do
  expect{ Foo.validate_arguments(nil) }.to raise_error(ArgumentError)
end

No need to alias (rspec 1.3).

like image 70
Ragmaanir Avatar answered Nov 14 '22 00:11

Ragmaanir


it "should raise ArgumentError for arguments that are not boolean" do
  lambda{ Foo.validate_arguments(something_non_boolean) }.should raise_error(ArgumentError)
end
like image 30
JHurrah Avatar answered Nov 13 '22 22:11

JHurrah


Unless it's very important that you throw an exception for non-boolean values, I think it would be more elegant to coerce the value to a boolean, for example with !!:

baz = !! options.fetch(:baz, true)

That way the client code can pass any truthy or falsy value, but you can still be sure that the value you work with is a proper boolean. You could also use the ternary operator (e.g. baz = options.fetch(:baz, true) ? true : false if you feel that !! is unclear.

like image 2
Theo Avatar answered Nov 14 '22 00:11

Theo