RSpec + FactoryGirl and controller specs - ruby-on-rails

I'm trying to add FactoryGirl support the default scaffolded specs in my controllers and I can't seem to find the correct syntax.
Here's an example test:
describe "POST create" do
describe "with valid params" do
it "creates a new Course" do
expect {
post :create, {:course => valid_attributes}, valid_session
}.to change(Course, :count).by(1)
end
do
Which I replace by:
describe "POST create" do
describe "with valid params" do
it "creates a new Course" do
expect {
post :create, course: FactoryGirl.build(:course)
}.to change(Course, :count).by(1)
end
do
spec/factories/courses.rb
FactoryGirl.define do
factory :course do
association :provider
name "Course name"
description "course description"
end
end
app/models/course.rb
class Course < ActiveRecord::Base
validates :name, :presence => true
validates :description, :presence => true
validates :provider_id, :presence => true
has_many :terms
belongs_to :provider
end
app/controllers/courses_controller.rb
# POST /courses
# POST /courses.json
def create
#course = Course.new(course_params)
respond_to do |format|
if #course.save
format.html { redirect_to #course, notice: 'Course was successfully created.' }
format.json { render action: 'show', status: :created, location: #course }
else
format.html { render action: 'new' }
format.json { render json: #course.errors, status: :unprocessable_entity }
end
end
end
It usually fails with: "ActionController::ParameterMissing: param not found: course" does anyone have any idea?
Thanks!
Francis

Try:
describe "POST create" do
describe "with valid params" do
it "creates a new Course" do
expect {
post :create, course: FactoryGirl.attributes_for(:course, provider_id: 1)
}.to change(Course, :count).by(1)
end
end
end
Factory Girl uses attributes_for option to generate a hash of values as opposed to a Ruby object.

Related

Unable to create a model in Rspec via Post

I'm trying to create a User in Rspec:
require "rails_helper"
RSpec.describe UsersController, type: :controller do
describe "POST #index" do
it 'should create a user' do
post :create, {name: "name1", age: 25}.to_json, format: :json
# .............
But instead I get validation errors each time: name can't be blank, age can't be blank
The UserController accepts json:
def create
#user = User.new(params1)
if #user.save
render json: #user
else
render json: #user.errors, status: :unprocessable_entity
end
end
def params1
params.permit(:id, :name, :age)
end
The parameters sent to create shouldn't be a json String but a Hash.
From the rspec documentation :
require "rails_helper"
RSpec.describe WidgetsController, :type => :controller do
describe "responds to" do
it "responds to custom formats when provided in the params" do
post :create, { :widget => { :name => "Any Name" }, :format => :json }
expect(response.content_type).to eq "application/json"
end
end
end
So your test should be :
require "rails_helper"
RSpec.describe UsersController, type: :controller do
describe "POST #create" do
it 'should create a user' do
post :create, { user: {name: "name1", age: 25}, :format => :json }
...

Failing RSpec tests of Controller with nested resource and associated FactoryGirl objects

I'm building a project to learn Rails and testing, and struggling to troubleshoot errors in an RSpec test of a controller that directs a nested resource. My code works as expected in a browser. I believe the problem relates to my test set-up and the associations of FactoryGirl objects. I need help troubleshooting and fixing the controller spec.
Here's the cardio_exercises_controller.rb
class CardioExercisesController < ApplicationController
# :get_member is defined in the private method at the bottom of this file,
# and takes the member_id provided by the routing and
#converts it to a #member object.
before_action :get_member
# GET member/1/cardio_exercises
# GET member/1/cardio_exercises.json
def index
#cardio_exercises = #member.cardio_exercises
end
# GET member/1/cardio_exercises/1
# GET member/1/cardio_exercises/1.json
def show
cardio_exercise = #member.cardio_exercises.find(params[:id])
end
# GET member/1/cardio_exercises/new
def new
#member = Member.find(params[:member_id])
#cardio_exercise = #member.cardio_exercises.build
end
# GET member/1/cardio_exercises/1/edit
def edit
#cardio_exercise = #member.cardio_exercises.find(params[:id])
end
# POST member/1/cardio_exercises
# POST member/1/cardio_exercises.json
def create
#cardio_exercise = #member.cardio_exercises.build(cardio_exercise_params)
if #cardio_exercise.save
flash[:success] = "Cardio exercise was successfully created."
redirect_to member_cardio_exercises_path(#member)
else
render 'new'
end
end
# PATCH/PUT member/1/cardio_exercises/1
# PATCH/PUT member/1/cardio_exercises/1.json
def update
#cardio_exercise = #member.cardio_exercises.find(params[:id])
if #cardio_exercise.update(cardio_exercise_params)
flash[:success] = "Cardio exercise was successfully updated."
redirect_to member_cardio_exercises_path(#member)
else
render 'edit'
end
end
# DELETE member/1/cardio_exercises/1
# DELETE member/1/cardio_exercises/1.json
def destroy
#cardio_exercise = #member.cardio_exercises.find(params[:id])
#cardio_exercise.destroy
respond_to do |format|
format.html { redirect_to (member_cardio_exercises_path(#member)), notice: 'Cardio exercise was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# The get_member action converts the member_id given by the routing
# into an #member object, for use here and in the view.
def get_member
#member = Member.find(params[:member_id])
end
def cardio_exercise_params
params.require(:cardio_exercise).permit(:title, :duration, :calories_burned, :date, :member_id)
end
end
Here's the cardio_exercises_controller_spec.rb
require 'rails_helper'
RSpec.describe CardioExercisesController, :type => :controller do
before :each do
#member = FactoryGirl.create(:member)
#cardio_exercise = FactoryGirl.create(:cardio_exercise)
#cardio_exercise_attributes = FactoryGirl.attributes_for(:cardio_exercise, :member_id => #member)
end
describe "GET index" do
it "assigns all cardio_exercises as #member.cardio_exercises" do
get :index, { :member_id => #member }
expect(assigns(:cardio_exercises)).to eq(#member.cardio_exercises)
end
end
describe "GET show" do
it "assigns the requested cardio_exercise as #member.cardio_exercise" do
get :show, { :member_id => #member, :id => #cardio_exercise }
expect(assigns(:cardio_exercise)).to eq(#member.cardio_exercise)
end
end
describe "GET new" do
it "assigns a new cardio_exercise as #member.cardio_exercise" do
get :new, { :member_id => #member }
expect(assigns(:cardio_exercise)).to be_a_new(CardioExercise)
end
end
describe "GET edit" do
it "assigns the requested cardio_exercise as #member.cardio_exercise" do
end
end
describe "POST create" do
describe "with valid params" do
it "creates a new CardioExercise" do
expect {
post :create, { :member_id => #member, :cardio_exercise => #cardio_exercise_attributes }
}.to change(CardioExercise, :count).by(1)
end
it "assigns a newly created cardio_exercise as #cardio_exercise" do
post :create, { :member_id => #member, :cardio_exercise => #cardio_exercise_attributes }
expect(assigns(:cardio_exercise)).to be_a(CardioExercise)
expect(assigns(:cardio_exercise)).to be_persisted
end
it "redirects to the created cardio_exercise" do
post :create, { :member_id => #member, :cardio_exercise => #cardio_exercise_attributes }
expect(response).to redirect_to(CardioExercise.last)
end
end
end
describe "PUT update" do
describe "with invalid params" do
xit "updates the requested cardio_exercise" do
#put :update, { id: #member.id, member_id: cardio_exercise: #cardio_exercise.id }
end
xit "assigns the requested cardio_exercise as #member.cardio_exercise" do
end
xit "redirects to the cardio_exercise" do
end
end
describe "with invalid params" do
xit "assigns the cardio_exercise as #member.cardio_exercise" do
end
xit "re-renders the 'edit' template" do
expect(response).to render_template("edit")
end
end
end
describe "DELETE destroy" do
it "destroys the requested cardio_exercise" do
expect {
delete :destroy, { :member_id => #member, :id => #cardio_exercise }
}.to change(CardioExercise, :count).by(-1)
end
it "redirects to the cardio_exercises list" do
delete :destroy, { :member_id => #member, :id => #cardio_exercise }
expect(response).to redirect_to(member_cardio_exercises_url)
end
end
end
These are the relevant factories:
FactoryGirl.define do
factory :cardio_exercise do
title "My cardio exercise"
duration 30
calories_burned 300
date "2014-11-15"
association :member
end
end
FactoryGirl.define do
factory :member do
first_name {Faker::Name.first_name}
last_name {Faker::Name.last_name}
age 21
height 75
weight 195
goal "fffff" * 5
start_date "2014-11-15"
end
end
routes.rb contains:
resources :members do
resources :cardio_exercises
end
members.rb contains:
has_many :cardio_exercises, :dependent => :destroy
cardio_exercises.rb contains:
belongs_to :member
Rspec Failures/Errors:
1) CardioExercisesController GET show assigns the requested cardio_exercise as #member.cardio_exercise
Failure/Error: get :show, { :member_id => #member, :id => #cardio_exercise }
ActiveRecord::RecordNotFound:
Couldn't find CardioExercise with 'id'=25 [WHERE "cardio_exercises"."member_id" = $1]
2) CardioExercisesController POST create with valid params redirects to the created cardio_exercise
Failure/Error: expect(response).to redirect_to(CardioExercise.last)
NoMethodError:
undefined method `cardio_exercise_url' for #<CardioExercisesController:0x00000008bba960>
3) CardioExercisesController DELETE destroy destroys the requested cardio_exercise
Failure/Error: delete :destroy, { :member_id => #member, :id => #cardio_exercise }
ActiveRecord::RecordNotFound:
Couldn't find CardioExercise with 'id'=34 [WHERE "cardio_exercises"."member_id" = $1]
4) CardioExercisesController DELETE destroy redirects to the cardio_exercises list
Failure/Error: delete :destroy, { :member_id => #member, :id => #cardio_exercise }
ActiveRecord::RecordNotFound:
Couldn't find CardioExercise with 'id'=35 [WHERE "cardio_exercises"."member_id" = $1]
I think the Record Not Found errors indicate a problem with the associations between the member and cardio exercise models. The controller isn't finding the cardio exercise by its id. What have I missed in setting things up for RSpec? What's the best way to fix the set up?
The Undefined method error appears to be caused by my calling the last method on CardioExercise. I'm posting to the create method in the example. CardioExercise is the class. Can someone explain why that call triggers the error, and how to fix it?
I appreciate any help!
You create two independent objects/records: member and cardio_exercise.
You should pass #member to factory cardio_exercise to connect them.
#member = FactoryGirl.create(:member)
#cardio_exercise = FactoryGirl.create(:cardio_exercise, member: #member)
PS When you create cardio_exercise without setup member factory creates new record in table members and assign cardio_exercise with this new record
UPDATE
about "GET index"
You create #member without any associated cardio_exercises. You added them later and object #member knows nothing about it. You should reload object to fetch data from DB
expect(assigns(:cardio_exercises)).to eq(#member.reload.cardio_exercises)
and sometimes I convert relations to array and sort result to avoid failing tests when order is different

RSpec controller tests of PUT update action on nested resource

I'm learning Rails and how to test using RSpec. I need help completing an RSpec controller test of the PUT update action. The controller directs a nested resource. The nested route and related program code work as expected in a web browser. I only need help writing the RSpec test for the PUT update action. I have passing tests of the other actions performed by the controller.
I know that the path and both parent and child ids must be passed to the put method, but I'm confused about the following: (1) how to properly set up the PUT update test using FactoryGirl objects, and (2) the proper RSpec syntax to pass the path and ids into the PUT method.
The relevant routes from rake routes:
PATCH /members/:member_id/cardio_exercises/:id(.:format) cardio_exercises#update
PUT /members/:member_id/cardio_exercises/:id(.:format) cardio_exercises#update
routes.rb contains:
resources :members do
resources :cardio_exercises
end
members.rb contains:
has_many :cardio_exercises, :dependent => :destroy
cardio_exercises.rb contains:
belongs_to :member
The relevant factories:
FactoryGirl.define do
factory :cardio_exercise do
title "My cardio exercise"
duration 30
calories_burned 300
date "2014-11-15"
association :member
end
end
FactoryGirl.define do
factory :member do
first_name {Faker::Name.first_name}
last_name {Faker::Name.last_name}
age 21
height 75
weight 195
goal "fffff" * 5
start_date "2014-11-15"
end
end
The cardio_exercises_controller.rb
class CardioExercisesController < ApplicationController
# :get_member is defined in the private method at the bottom of this file,
# and takes the member_id provided by the routing and
#converts it to a #member object.
before_action :get_member
# GET member/1/cardio_exercises
# GET member/1/cardio_exercises.json
def index
#cardio_exercises = #member.cardio_exercises
end
# GET member/1/cardio_exercises/1
# GET member/1/cardio_exercises/1.json
def show
cardio_exercise = #member.cardio_exercises.find(params[:id])
end
# GET member/1/cardio_exercises/new
def new
#member = Member.find(params[:member_id])
#cardio_exercise = #member.cardio_exercises.build
end
# GET member/1/cardio_exercises/1/edit
def edit
#cardio_exercise = #member.cardio_exercises.find(params[:id])
end
# POST member/1/cardio_exercises
# POST member/1/cardio_exercises.json
def create
#cardio_exercise = #member.cardio_exercises.build(cardio_exercise_params)
if #cardio_exercise.save
flash[:success] = "Cardio exercise was successfully created."
redirect_to member_cardio_exercises_path(#member)
else
render 'new'
end
end
# PATCH/PUT member/1/cardio_exercises/1
# PATCH/PUT member/1/cardio_exercises/1.json
def update
#cardio_exercise = #member.cardio_exercises.find(params[:id])
if #cardio_exercise.update(cardio_exercise_params)
flash[:success] = "Cardio exercise was successfully updated."
redirect_to member_cardio_exercises_path(#member)
else
render 'edit'
end
end
# DELETE member/1/cardio_exercises/1
# DELETE member/1/cardio_exercises/1.json
def destroy
#cardio_exercise = #member.cardio_exercises.find(params[:id])
#cardio_exercise.destroy
respond_to do |format|
format.html { redirect_to (member_cardio_exercises_path(#member)), notice: 'Cardio exercise was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# The get_member action converts the member_id given by the routing
# into an #member object, for use here and in the view.
def get_member
#member = Member.find(params[:member_id])
end
def cardio_exercise_params
params.require(:cardio_exercise).permit(:title, :duration, :calories_burned, :date, :member_id)
end
end
The cardio_exercises_controller_spec.rb and my attempt to set up several tests of the PUT update action:
require 'rails_helper'
RSpec.describe CardioExercisesController, :type => :controller do
before :each do
#member = FactoryGirl.create(:member)
#cardio_exercise = FactoryGirl.create(:cardio_exercise, member: #member)
#cardio_exercise_attributes = FactoryGirl.attributes_for(:cardio_exercise, :member_id => #member)
#cardio_exercise_update_attributes = FactoryGirl.attributes_for(:cardio_exercise, :title => "Your Cardio Exercise", :member_id => #member)
end
describe "GET index" do
it "assigns all cardio_exercises as #member.cardio_exercises" do
get :index, { :member_id => #member }
expect(assigns(:cardio_exercises)).to eq(#member.reload.cardio_exercises)
end
end
describe "GET show" do
it "assigns the requested cardio_exercise as #cardio_exercise" do
get :show, { :member_id => #member, :id => #cardio_exercise }
expect(assigns(:cardio_exercise)).to eq(#cardio_exercise)
end
end
describe "GET new" do
it "assigns a new cardio_exercise as #member.cardio_exercise" do
get :new, { :member_id => #member }
expect(assigns(:cardio_exercise)).to be_a_new(CardioExercise)
end
end
describe "GET edit" do
it "assigns the requested cardio_exercise as #member.cardio_exercise" do
get :edit, { :member_id => #member, :id => #cardio_exercise }
expect(assigns(:cardio_exercise)).to eq(#cardio_exercise)
end
end
describe "POST create" do
describe "with valid params" do
it "creates a new CardioExercise" do
expect {
post :create, { :member_id => #member, :cardio_exercise => #cardio_exercise_attributes }
}.to change(CardioExercise, :count).by(1)
end
it "assigns a newly created cardio_exercise as #cardio_exercise" do
post :create, { :member_id => #member, :cardio_exercise => #cardio_exercise_attributes }
expect(assigns(:cardio_exercise)).to be_a(CardioExercise)
expect(assigns(:cardio_exercise)).to be_persisted
end
it "redirects to the created cardio_exercise" do
post :create, { :member_id => #member, :cardio_exercise => #cardio_exercise_attributes }
expect(response).to redirect_to(member_cardio_exercises_path(#member))
end
end
end
describe "PUT update" do
describe "with valid params" do
it "updates the requested cardio_exercise" do
put :update, { :member_id => #member, :id => #cardio_exercise_update_attributes }
#member.cardio_exercise.reload
put :update, { :member_id => #member, :id => #cardio_exercise_update_attributes}
end
it "assigns the requested cardio_exercise as #member.cardio_exercise" do
put :update, { :member_id => #member, :cardio_exercise => #cardio_exercise_update_attributes = FactoryGirl.attributes_for(:cardio_exercise, :title => "Your Cardio Exercise", :member_id => #member)}
expect(assigns(:cardio_exercises)).to eq(#member.cardio_exercises)
end
it "redirects to the cardio_exercise" do
put :update, { :member_id => #member, :id => #cardio_exercise }
expect(response).to redirect_to(#member.cardio_exercise)
end
end
describe "with invalid params" do
xit "assigns the cardio_exercise as #member.cardio_exercise" do
end
xit "re-renders the 'edit' template" do
expect(response).to render_template("edit")
end
end
end
describe "DELETE destroy" do
it "destroys the requested cardio_exercise" do
expect {
delete :destroy, { :member_id => #member, :id => #cardio_exercise }
}.to change(CardioExercise, :count).by(-1)
end
it "redirects to the cardio_exercises list" do
delete :destroy, { :member_id => #member, :id => #cardio_exercise }
expect(response).to redirect_to(member_cardio_exercises_url)
end
end
end
Please review my test set-up and the PUT update tests. Specifically, is my set-up the correct way to test the PUT update action?
How do I change the set-up and/or tests of the controller's update action so that:
(1) my tests match my routes for the update action?
(2) I pass the necessary parent and child ids in the correct RSpec syntax so records can be found?
I appreciate any help!
You must pass the member_id, the cardio_exercise's id, AND the cardio_exercise parameters to update:
put :update, {
:member_id => #member,
:id => #cardio_exercise.id,
:cardio_exercise => #cardio_exercise_update_attributes
}

Scaffold generated rspec controller test returns nil on Factory created model

Even when the following line works just fine on the model test:
game = FactoryGirl.create(:game)
It doesn't seem to do it on games_controller_rspec.rb.
describe "GET index" do
it "assigns all games as #games" do
game = FactoryGirl.create(:game)
get :index, {}
expect(assigns(:games)).to eq([game])
end
end
And I keep getting "expected: [...]
got: nil"
This is the factory:
FactoryGirl.define do
factory :game do |f|
f.team_a_id { 1 }
f.team_b_id { 2 }
end
end
Full games_controller.rb:
class GamesController < ApplicationController
before_action :set_game, only: [:show, :edit, :update, :destroy]
before_filter :check_admin_status, only: [:new, :edit, :create, :update, :destroy]
def index
#games = Game.all
end
def show
end
def new
#game = Game.new
end
def edit
end
def create
#game = Game.new(game_params)
respond_to do |format|
if #game.save
format.html { redirect_to #game, notice: 'Game was successfully created.' }
format.json { render action: 'show', status: :created, location: #game }
else
format.html { render action: 'new' }
format.json { render json: #game.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #game.update(game_params)
format.html { redirect_to #game, notice: 'Game was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #game.errors, status: :unprocessable_entity }
end
end
end
def destroy
#game.destroy
respond_to do |format|
format.html { redirect_to games_url }
format.json { head :no_content }
end
end
private
def set_game
#game = Game.find(params[:id])
end
def game_params
params.require(:game).permit(:team_a_id, :team_b_id)
end
end
Full games_controller_spec.rb:
require 'spec_helper'
describe GamesController do
include Devise::TestHelpers
let(:valid_attributes) { { "team_a_id" => "1" } }
let(:valid_session) { {} }
describe "GET index" do
it "assigns all games as #games" do
game = FactoryGirl.create(:game)
get :index, {}
expect(assigns(:games)).to eq([game])
end
end
describe "GET show" do
it "assigns the requested game as #game" do
game = FactoryGirl.create(:game)
get :show, {:id => game.to_param}, valid_session
expect(assigns(:game)).to eq(game)
end
end
describe "GET new" do
it "assigns a new game as #game" do
get :new, {}, valid_session
expect(assigns(:game)).to be_a_new(Game)
end
end
describe "GET edit" do
it "assigns the requested game as #game" do
game = FactoryGirl.create(:game)
get :edit, {:id => game.to_param}, valid_session
expect(assigns(:game)).to eq(game)
end
end
describe "POST create" do
describe "with valid params" do
it "creates a new Game" do
expect {
post :create, {:game => valid_attributes}, valid_session
}.to change(Game, :count).by(1)
end
it "assigns a newly created game as #game" do
post :create, {:game => valid_attributes}, valid_session
expect(assigns(:game)).to be_a(Game)
expect(assigns(:game)).to be_persisted
end
it "redirects to the created game" do
post :create, {:game => valid_attributes}, valid_session
expect(response).to redirect_to(Game.last)
end
end
describe "with invalid params" do
it "assigns a newly created but unsaved game as #game" do
allow_any_instance_of(Game).to receive(:save).and_return(false)
post :create, {:game => { "team_a_id" => "invalid value" }}, valid_session
expect(assigns(:game)).to be_a_new(Game)
end
it "re-renders the 'new' template" do
allow_any_instance_of(Game).to receive(:save).and_return(false)
post :create, {:game => { "team_a_id" => "invalid value" }}, valid_session
expect(response).to render_template("new")
end
end
end
describe "PUT update" do
describe "with valid params" do
it "updates the requested game" do
game = Game.create! valid_attributes
expect_any_instance_of(Game).to receive(:update).with({ "team_a_id" => "1" })
put :update, {:id => game.to_param, :game => { "team_a_id" => "1" }}, valid_session
end
it "assigns the requested game as #game" do
game = Game.create! valid_attributes
put :update, {:id => game.to_param, :game => valid_attributes}, valid_session
expect(assigns(:game)).to eq(game)
end
it "redirects to the game" do
game = Game.create! valid_attributes
put :update, {:id => game.to_param, :game => valid_attributes}, valid_session
expect(response).to redirect_to(game)
end
end
describe "with invalid params" do
it "assigns the game as #game" do
game = Game.create! valid_attributes
allow_any_instance_of(Game).to receive(:save).and_return(false)
put :update, {:id => game.to_param, :game => { "team_a_id" => "invalid value" }}, valid_session
expect(assigns(:game)).to eq(game)
end
it "re-renders the 'edit' template" do
game = Game.create! valid_attributes
allow_any_instance_of(Game).to receive(:save).and_return(false)
put :update, {:id => game.to_param, :game => { "team_a_id" => "invalid value" }}, valid_session
expect(response).to render_template("edit")
end
end
end
describe "DELETE destroy" do
it "destroys the requested game" do
game = Game.create! valid_attributes
expect {
delete :destroy, {:id => game.to_param}, valid_session
}.to change(Game, :count).by(-1)
end
it "redirects to the games list" do
game = Game.create! valid_attributes
delete :destroy, {:id => game.to_param}, valid_session
expect(response).to redirect_to(games_url)
end
end
end
Found it. The problem was with user privileges. I'm using devise and only allow certain methods to regular users. Therefore the result for them would be nil, unless i take the test with an admin user.
Basically I had to set an admin user on spec to make it work.
This is how you do it:
1) Write controller_macros.rb inside spec/support
module ControllerMacros
def login_admin
before(:each) do
#request.env["devise.mapping"] = Devise.mappings[:admin]
sign_in FactoryGirl.create(:admin) # Using factory girl as an example
end
end
def login_user
before(:each) do
#request.env["devise.mapping"] = Devise.mappings[:user]
user = FactoryGirl.create(:user)
user.confirm!
sign_in user
end
end
end
2) Add it to spec_helper
RSpec.configure do |config|
config.include Devise::TestHelpers, :type => :controller
config.extend ControllerMacros, :type => :controller
end
3) Set the user to admin on your controller_spec
describe GamesController do
login_admin
describe "GET index" do
game = FactoryGirl.create(:game)
get :index, {}, valid_session
expect(assigns(:games).to eq([game])
end
My User factory:
FactoryGirl.define do
factory :user do
email "nn#nnn.com"
password "12345654321"
password_confirmation { "12345654321" }
factory :admin do
after(:create) { |user| user.update_attribute :admin, true }
end
end
end
Founded here.
I'm having the same exact issue. I found a post on here (I forgot to bookmark it and am having trouble finding it) that said to replace your "get :index, {}" with "controller.index" and see if it works. It worked for me when I did this. They also said it was a routing issue. What I don't understand is why, and how to fix it so that I can use the standard code that's generated from the scaffold. My route tests pass, but yet there's a routing issue that's causing "get" not to work in these tests? I don't understand.
EDIT:
Just found the post. Check it out here. The OP never comes back to tell what the issue was our how they fixed it though. I would love to know as I'm frustrated trying to figure out how to get this working.

rails rspec - (2nd test) Expected response to be a <:redirect>, but was <200>

Expected response to be a <:redirect>, but was <200>
My tests has:
describe "Link POST #create" do
context "with valid attributes" do
it "creates a new link" do
expect{
post :create, link: FactoryGirl.create(:link, :group => #group)
}.to change(Link,:count).by(1)
end
it "redirects to the new link" do
post :create, link: FactoryGirl.create(:link, :group => #group)
# response.should redirect_to #link # Link.unscoped.last
response.should redirect_to Link.unscoped.last # render_template :show
end
end
The first test passes but the second fails.
My code is:
def create
#link = Link.new(params[:link])
respond_to do |format|
if #link.save
flash[:notice] = 'Link was successfully created.'
format.html { redirect_to(#link) }
format.xml { render :xml => #link, :status => :created, :location => #link }
else
#selected_group = params[:group_id]
format.html { render :action => "new" }
format.xml { render :xml => #link.errors, :status => :unprocessable_entity }
end
end
end
I've tried redirect and render but can't get the 2nd test to pass.
Here's something that should make it work:
describe "Link POST #create" do
context "with valid attributes" do
def do_post( format = 'html' )
attributes = FactoryGirl.build(:link).attributes.merge( :group_id => #group.id )
post :create, :link => attributes, :format => 'html'
end
it "creates a new link" do
expect{
do_post
}.to change(Link,:count).by(1)
end
it "redirects to the new link" do
do_post
response.should redirect_to( assigns[:link] )
end
end
The first spec was working only because you were calling FactoryGirl.create so a record was being created out of the controller, but most likely the controller call wasn't working.

Resources