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??
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.
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
精彩评论