Should raise_error(ArgumentError) resulting in NoMethodError

Environment

ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.4.0]
rspec (1.3.0)

Code

def currency_to_dollars(currency_amount)
  raise ArgumentError("Currency amount can't be nil") if

currency_amount.nil?
end

Spec

it "should raise an ArgumentError if currency_amount is nil" do
  lambda { @service.currency_to_dollars(nil) }.should

raise_error(ArgumentError)
end

Results in this failure:
1)
‘Service should raise an ArgumentError if currency_amount is nil’ FAILED
expected ArgumentError, got #<NoMethodError: undefined method
ArgumentError' for #<Service:0x0000010087e5f0>> test/spec/service_spec.rb:92:inblock (2 levels) in <top (required)>’

Changing the test to either of these two variants allows the the to
pass:

lambda { @service.currency_to_dollars(nil) }.should

raise_error(StandardError)
lambda { @service.currency_to_dollars(nil) }.should raise_error

Why am I unable to test for a specific StandardError subclass?

Thanks in advance for any help.
BP

FYI, the same thing happens with rspec 2.0.0.beta.20 as well:

  1. Service should raise an ArgumentError if currency_amount is nil
    Failure/Error: lambda
    { @service.currency_to_dollars(nil) }.should
    raise_error(ArgumentError)
    expected ArgumentError, got #<NoMethodError: undefined method
    `ArgumentError’ for #Service:0x000001029665d8>

    ./test/spec/service_spec.rb:92:in `block (2 levels) in <top

(required)>’

On Aug 25, 2010, at 10:13 PM, Brian P. wrote:

Spec

it "should raise an ArgumentError if currency_amount is nil" do
  lambda { @service.currency_to_dollars(nil) }.should raise_error(ArgumentError)
end

Results in this failure:
1)
‘Service should raise an ArgumentError if currency_amount is nil’ FAILED
expected ArgumentError, got #<NoMethodError: undefined method `ArgumentError’ for #Service:0x0000010087e5f0>

This message is telling you there is no ArgumentError method, not that
the constant ArgumentError is missing. The method needs to be (adding
“.new”):

def currency_to_dollars(currency_amount)
  raise ArgumentError.new("Currency amount can't be nil") if 

currency_amount.nil?
end

test/spec/service_spec.rb:92:in `block (2 levels) in <top (required)>’

Changing the test to either of these two variants allows the the to pass:

lambda { @service.currency_to_dollars(nil) }.should raise_error(StandardError)
lambda { @service.currency_to_dollars(nil) }.should raise_error

These pass because NoMethodError, which is what is being thrown, is a
subclass of StandardError and Exception.

HTH,
David

On Aug 26, 2010, at 12:14 AM, David C. wrote:

currency_amount.nil?
1)
raise ArgumentError.new(“Currency amount can’t be nil”) if
currency_amount.nil?
end

You might see this form, too.

def currency_to_dollars(currency_amount)
  raise ArgumentError, "Currency amount can't be nil" if

currency_amount.nil?
end

Note the comma that separates the arguments to raise (Kernel#raise).

-Rob

lambda { @service.currency_to_dollars(nil) }.should raise_error

These pass because NoMethodError, which is what is being thrown, is
a subclass of StandardError and Exception.

HTH,
David


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users

Rob B.
[email protected] http://AgileConsultingLLC.com/
[email protected] http://GaslightSoftware.com/

smacks head Duh.

Thanks David and Rob!

On Aug 26, 12:35 am, Rob B. [email protected]