[rspec-devel] [ rspec-Bugs-8371 ] Mocking complaining about wrong number of arguments (odd)

noreply at rubyforge.org noreply at rubyforge.org
Thu Feb 8 10:16:07 EST 2007


Bugs item #8371, was opened at 2007-02-01 20:27
You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=3149&aid=8371&group_id=797

Category: mock module
Group: None
>Status: Closed
>Resolution: Rejected
Priority: 3
Submitted By: Rodrigo Kochenburger (divoxx)
Assigned to: Nobody (None)
Summary: Mocking complaining about wrong number of arguments (odd)

Initial Comment:
In this code http://pastie.caboo.se/37274 i'm trying to mock a model method while testing a controller. (Line 12)

The error being raised is also pasted in there. If i comment that line out and actually call the create method, the model raises the exception and everything works just fine...

I've already tried using .with(:any_args)

----------------------------------------------------------------------

>Comment By: David Chelimsky (dchelimsky)
Date: 2007-02-08 15:16

Message:
When you call this:

Person.should_receive(:create).and_raise(ActiveRecord::RecordInvalid)

the mock tries to create an instance of ActiveRecord::RecordInvalid) by calling #new. As it turns out, ActiveRecord::RecordInvalid.new requires that an ActiveRecord model instance gets passed in, which is not supported by RSpec. The docs indicate that you can supply an instantiated exception or a class. I'll update the docs to say that if supply the class that it must be able to be initialized with no args.

So you need to change your spec so that you pass in an instance of ActiveRecord::RecordInvalid, not just the class name.

Beware that the initializer of ActiveRecord::RecordInvalid looks like this:

    def initialize(record)
      @record = record
      super("Validation failed: #{@record.errors.full_messages.join(", ")}")
    end

So you have to supply a chain of stubs to satisfy the chain of calls:

model = mock("model")
errors = mock("errors")
    
model.stub!(:errors).and_return(errors)
errors.stub!(:full_messages).and_return([]) 
   Person.should_receive(:create).and_raise(ActiveRecord::RecordInvalid.new(model))

This is one of those tradeoffs that you have to deal with in rails. It violates OO principles (Law of Demeter in this case) in order to provide you w/ something that's really easy to *use*, but makes it really difficult to *test* in the process.

----------------------------------------------------------------------

Comment By: David Chelimsky (dchelimsky)
Date: 2007-02-01 21:37

Message:
RSpec version?
Rails version?

Also - try running the specs w/ the -b argument so you can get a more thorough backtrace.

----------------------------------------------------------------------

You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=3149&aid=8371&group_id=797


More information about the rspec-devel mailing list