Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RSpec test not invoking controller

I've got a simple test, pretty much what the scaffold generated, although I can't figure out why it's not working. Here's the situation:

I've got an AttachmentsController:

  # POST /attachments
  # POST /attachments.xml
  def create
    @attachment = Attachment.new(params[:attachment])
    @attachment.idea_id = params[:idea_id]

    respond_to do |format|
      if @attachment.save
        format.html { redirect_to(idea_path(params[:idea_id]), :notice => 'Attachment was successfully created.') }
        format.xml  { render :xml => @attachment, :status => :created, :location => @attachment }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @attachment.errors, :status => :unprocessable_entity }
      end

    end
  end
end

And a spec:

describe AttachmentsController do
  def mock_attachment(stubs={})
    @mock_attachment ||= mock_model(Attachment, stubs).as_null_object
  end

  describe "POST create" do
    describe "with valid params" do
      it "assigns a newly created attachment as @attachment" do
        Attachment.stub(:new).with({'these' => 'params'}) { mock_attachment(:save => true) }
        post :create,:attachment => {'these' => 'params'}
        assigns(:attachment).should be(mock_attachment)
      end

but this (and every other test in this spec) fails with something along the lines of

expected #<Attachment:33902000> => #<Attachment:0x2054db0 @name="Attachment_1001">
     got #<NilClass:4> => nil

Because, for reasons I can't figure out, AttachmentsController#create isn't being called.

The route is there:

POST   /attachments(.:format)          {:action=>"create", :controller=>"attachments"}

This is what the log says:

  Processing by AttachmentsController#create as HTML
  Parameters: {"attachment"=>{"these"=>"params"}}
Rendered text template (0.0ms)
Completed 302 Found in 52ms (Views: 23.1ms | ActiveRecord: 0.0ms)

I should also note that I can invoke the create code (and it works great) through the website itself.. it's just the tests that are failing.

So what would cause post() or get() not to invoke the controller like this??

like image 444
lambinator Avatar asked Jul 15 '11 07:07

lambinator


2 Answers

For future viewers of this question, the actual answer was posted by @solnic in a comment to the accepted answer: check your logs. In this case (and in my own situation) a redirect caused this problem, which was only visible in the logs.

like image 180
dacoinminster Avatar answered Oct 12 '22 01:10

dacoinminster


You could try should_receive and put it into before block as it's a better practice:

describe AttachmentsController do
  describe "POST create" do
    let(:attachment) { mock_attachment(:save => save_result) }

    subject { post :create, :attachment => params }

    before do
      Attachment.should_receive(:new).and_return(attachment)
    end

    describe "with valid params" do
      let(:attachment_params) { {'these' => 'params'} }
      let(:save_result) { true }

      it "assigns a newly created attachment as @attachment" do
        assigns(:attachment).should be(mock_attachment)
      end
    end
  end
end
like image 30
solnic Avatar answered Oct 12 '22 00:10

solnic