Created
August 17, 2011 13:56
-
-
Save olivierlacan/1151572 to your computer and use it in GitHub Desktop.
Issue testing create action with invalid parameters when using respond_to/respond_with in Rails 3.x
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Issue testing create action with invalid parameters when using respond_to/respond_with in Rails 3.x | |
When a new "thing" is saved without invalid params, the respond_with behavior is to render :new again. | |
But since the form has been submitted to :root/things/, what actually displays in the browser is http://:root/things and not http://:root/things/new. | |
Somehow this confuses the render_template test in RSpec and it believes the current template is "" instead of "new", which results in a failed test. | |
The only solution I found was to write the create action like this: | |
if @thing.save | |
respond_with @thing | |
else | |
render :new | |
end | |
But that kind of defeats the purpose of the respond_with elegance, doesn't it? | |
I'd love to hear feedback on this. I'm still new to Rails and especially new to testing. | |
You can find all the details below. | |
## Model | |
class Thing < ActiveRecord::Base | |
### schema | |
# name string | |
# store_id integer | |
### | |
has_and_belongs_to_many :stores | |
attr_accessible :name | |
validates :name, presence: true | |
end | |
## Controller | |
class ThingController < ApplicationController | |
respond_to :html, :json | |
(...) | |
def new | |
@thing = Thing.new | |
respond_with @thing | |
end | |
def create | |
@thing = Device.new(params[:thing]) | |
@thing.save | |
respond_with @thing | |
end | |
(...) | |
## RSpec Controller test | |
describe ThingController do | |
describe "POST create" do | |
describe "with invalid params" do | |
it "assigns a newly created but unsaved device as @thing" do | |
Thing.any_instance.stub(:save).and_return(false) | |
post :create, :thing => {} | |
assigns(:thing).should be_a_new(Thing) | |
end | |
it "re-renders the 'new' template" do | |
Thing.any_instance.stub(:save).and_return(false) | |
post :create, :thing => {} | |
response.should render_template("new") | |
end | |
end | |
end | |
## RSpec result | |
Failures: | |
1) ThingsController POST create with invalid params re-renders the 'new' template | |
Failure/Error: response.should render_template("new") | |
expecting <"new"> but rendering with <""> | |
# ./spec/controllers/things_controller_spec.rb:93:in `block (4 levels) in <top (required)>' | |
Finished in 0.78002 seconds | |
9 examples, 1 failure | |
## Log output | |
Started POST "/en/things" for 127.0.0.1 at 2011-08-17 09:35:38 -0400 | |
Processing by ThingsController#create as HTML | |
Parameters: {"utf8"=>"✓", "authenticity_token"=>"7J/MfJ/BHqVhIT4SCGlIYVy0lv+lpfkrHU63gFKZhUQ=", "thing"=>{"name"=>""}, "commit"=>"Save", "locale"=>"en"} | |
Rendered devices/_form.html.haml (4.5ms) | |
Rendered devices/new.html.haml within layouts/application (6.0ms) | |
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1 | |
(0.2ms) SELECT COUNT(*) FROM "stores" WHERE "stores"."user_id" = 1 | |
Completed 200 OK in 248ms (Views: 235.8ms | ActiveRecord: 1.7ms) | |
## Visual result | |
http://link.olivierlacan.com/9NRg |
Having the same issue, news on this?
be_redirect
works, but in logs you see how it doesn't redirect.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Try this: