[rspec-users] Testing create in Rails controller

Shane Mingins smingins at elctech.com
Mon Jun 11 04:16:16 EDT 2007


Hi All

So I am a first-time caller ;-) ... and have been trying to apply  
RSpec to the depot example in Dave Thomas' book as I build the  
application.

I am having a problem testing the admin controller create method and  
cannot quite see where I am going wrong so was hoping for a pointer :-)

My spec looks like:

describe AdminController do

   before(:each) do
     @product = mock("product")
     # Generally, prefer stub! over should_receive in setup.
     @product.stub!(:new_record?).and_return(false)
     Product.stub!(:new).and_return(@product)
   end

   it "should create a new, unsaved product on GET to new" do
       # Using should_receive here overrides the stub in setup. Even
       # though it is the same as the stub, using should_receive sets
       # an expectation that  will be verified. It also helps to
       # better express the intent of this example.
       Product.should_receive(:new).and_return(@product)
       get :new
   end

   it "should assign new product to template on GET to new" do
       get :new
       assigns[:product].should equal(@product)
   end

   it "should render 'product/new' on GET to new" do
     get :new
     response.should render_template(:new)
   end

   it "should tell the Product model to save a new product on POST to  
create" do
       attributes = {"title" => 'Apple Wireless Keyboard',
                     "description" => 'Really cool wireless keyboard',
                     "image_url" => 'a.gif',
                     "price" => 1.00}

       Product.should_receive(:new).with(attributes)
       Product.should_receive(:save).with(:no_arg)

       post :create, :product => attributes
   end

end


Which I copied and modified from the example.

The code in the controller looks like:

   def create
     @product = Product.new(params[:product])
     if @product.save
       flash[:notice] = 'Product was successfully created.'
       redirect_to :action => 'list'
     else
       render :action => 'new'
     end
   end


I am guessing that I haven't quite got the mock/stub setup correctly??

The error I get is:

1)
NoMethodError in 'AdminController should tell the Product model to  
save a new product on POST to create'
You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.save
/Users/smingins/Work/depot/config/../app/controllers/ 
admin_controller.rb:25:in `create'
./spec/controllers/admin_controller_spec.rb:41:

Finished in 0.226535 seconds


I have been playing around with things but without any luck.  The nil  
error does strike me as rather odd but the test reads as I would have  
thought it should ... but obviously I am missing something.

Cheer
Shane


More information about the rspec-users mailing list