RSpec: controller POST create

147 views
Skip to first unread message

Soichi Ishida

unread,
Nov 12, 2012, 4:19:47 AM11/12/12
to rubyonra...@googlegroups.com
Rails 3.1.3
rspec-rails (2.11.4)
rspec 2.11.1

I am new to rspec. I don't quite understand tests for POST create part.

I have generated scaffold, and simultaneously it generated
controller_spec.rb as well.

it "assigns a newly created plan as @plan" do
post :create, {:plan => valid_attributes}, valid_session
assigns(:plan).should be_a(Plan)
assigns(:plan).should be_persisted
end

is the default POST create test. It raises a failure, if I changed the
validations of Plan

class Plan < ActiveRecord::Base
validates :give_take, :presence => true
validates :flight_name_id, :presence => true
validates :day_departure, :presence => true
validates :weight, :presence => true
end

The failure message is

1) PlansController POST create with valid params assigns a newly
created plan as @plan
Failure/Error: assigns(:plan).should be_persisted
expected persisted? to return true, got false
# ./spec/controllers/plans_controller_spec.rb:117:in `block (4
levels) in <top (required)>'


If my understanding is correct, be_persisted is testing if the newly
created model instance is properly stored in DB.

I understand that my way is rather opposite: building test methods after
setting actual codes. But first I need to understand RSpec.

I have also setup FactoryGirl

FactoryGirl.define do
factory :plan do
sequence(:give_take) { |n| [ 0, 1 ][n%2] }
sequence(:weight) { | n | n }
sequence(:check_in) { |c| [ true, false ][c%2] }
sequence(:flight_name_id) { |n| n }
day_departure Date.new(2012, 12, 1)
end
end

which does work.

Question:
Can you show me how to pass the object to create method WITH valid
attributes?

Thanks in advance

soichi

--
Posted via http://www.ruby-forum.com/.

Norbert Melzer

unread,
Nov 12, 2012, 4:37:55 AM11/12/12
to rubyonra...@googlegroups.com

Where do you define valid attributes?

Have you tried post :plan => Factory(:plan)?

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Mirri Kim

unread,
Nov 12, 2012, 4:41:02 AM11/12/12
to rubyonra...@googlegroups.com
On your controller, use `create!` to see what is preventing the save.

Soichi Ishida

unread,
Nov 12, 2012, 4:41:25 AM11/12/12
to rubyonra...@googlegroups.com
> Where do you define valid attributes?
>

You mean,

def valid_attributes
FactoryGirl.build(:plan).attributes
end

in plans_controller_spec.rb ? Even if so, I am not sure if it's a right
way.

Soichi Ishida

unread,
Nov 12, 2012, 5:13:31 AM11/12/12
to rubyonra...@googlegroups.com
> On your controller, use `create!` to see what is preventing the save.

Sorry, I don't quite understand what you mean.

my plans_controller.rb has

def create
@plan = Plan.new(params[:plan])

respond_to do |format|
if @plan.save
format.html { redirect_to @plan, notice: 'Plan was successfully
created.' }
format.json { render json: @plan, status: :created, location:
@plan }
else
format.html { render action: "new" }
format.json { render json: @plan.errors, status:
:unprocessable_entity }
end
end
end

which scaffold generated by default.

Norbert Melzer

unread,
Nov 12, 2012, 5:48:07 AM11/12/12
to rubyonra...@googlegroups.com

What he wants to say is that you should log or print the error-array of your model and look what exactly doesn't fit into your validations.

Mirri Kim

unread,
Nov 12, 2012, 6:07:32 AM11/12/12
to rubyonra...@googlegroups.com
Hi Soichi,

You can temporarily do `if @plan.save!` to raise an error instead of just having it return false and not give you any feedback. Doing this is okay because you should not bother testing your validations as far as the controller is concerned (you do that on your model). In any case, try to validate your factory first (if you plan to use `FactoryGirl.attributes_for`) to prevent problems such as this.

Soichi Ishida

unread,
Nov 14, 2012, 5:05:17 AM11/14/12
to rubyonra...@googlegroups.com
> You can temporarily do `if @plan.save!` to raise an error instead of
> just
> having it return false and not give you any feedback.

the same result including

describe "with invalid params" do
...

part failures.


Doing this is okay
> In any case, try to
> validate your factory first (if you plan to use
> `FactoryGirl.attributes_for`) to prevent problems such as this.

I tried

def valid_attributes
{
:weight => 4,
:flight_name_id => 55,
:give_take => 0,
:day_departure => "2012-12-22",
:check_in => true
}
end

In other words, running the test without FactoryGirl. But it returns


13) PlansController POST create with valid params creates a new Plan
Failure/Error: post :create, {:plan => valid_attributes},
valid_session
ActiveRecord::RecordInvalid:
Validation failed: Give take can't be blank, Flight name can't be
blank, Day departure can't be blank, Weight can't be blank

So it looks like attributes are passed properly at all.
I am completely lost here...

soichi
Reply all
Reply to author
Forward
0 new messages