Rails Testing: Failing "Create" specs with deadlocked controllers - ruby-on-rails

I have controllers - Survey, Questions and Options.
I cannot save Survey without creating Questions first. And in turn Questions cannot be created creating Options first. How to get "create" specs pass for Survey controller...
Surveys_Controller_spec.rb
describe "POST 'create'" do
before(:each) do
#user = FactoryGirl.create(:activated_user)
login_user(#user)
end
context "with valid parameters" do
let(:parameters) { { :title => "Title of the Survey", :description => "description", :activated => "false", :participant_info => "0", :is_draft => "true", :thank_you_message => "Thank You", :user_id => #user.id } }
it "creates a new survey" do
expect { post :create, :survey => parameters }.to change(Survey, :count).by(1)
end
Surveys_Controller.rb
def create
#survey = convert_enums(current_user.surveys.new(params[:survey]), params)
respond_to do |format|
if #survey.save
format.html { redirect_to dashboard_path, :notice => "Survey was successfully created!"}
else
format.html { render :new }
end
end

Related

Cancancan gem while using Rspec

I have problem with my feature test for users creating new content. It passes only when I comment or delete this line in my controller. It looks like factory :user doesn't have ability to create new content. I checked factory using seperate test to check if it has ability to create new word and it has. What can be problem here?
authorize! :create, #word, :message => "Musisz się zalogować, aby dodać nowe słówko."
words_controller.rb
def create
authorize! :create, #word, :message => "Musisz się zalogować, aby dodać nowe słówko."
#user = current_user
#word = #user.words.build(word_params)
respond_to do |format|
if #word.save
format.html {
redirect_to new_word_path
flash[:notice] = 'Słówko zostało prawidłowo zapisane. Dodaj następne!'
}
format.json { render :show, status: :created, location: #word }
else
format.html { render :new }
format.json { render json: #word.errors, status: :unprocessable_entity }
end
end
end
user_creates_word_spec.rb
require 'spec_helper'
feature 'User creates word' do
before(:all) do
category = FactoryGirl.create(:category)
10.times { word = FactoryGirl.create(:word) }
sign_in
expect(page).to have_content 'Wyloguj się'
visit game_words_path
click_link('Dodaj słówko')
end
scenario 'with valid input' do
fill_in 'Angielski', with: 'house'
fill_in 'Polski', with: 'dom'
find(:css, ".check_boxes[value='1']").set(true)
click_button 'Zapisz'
expect(page).to have_content 'Słówko zostało prawidłowo zapisane.'
end
end
test to check if user factory has ability to create new word
it "can create new word" do
user = FactoryGirl.create(:user)
ability = Ability.new(user)
word = Word.new(user: user)
expect { ability.should be_able_to(:create, word)}
end
I changed this lines:
authorize! :create, #word, :message => "Musisz się zalogować, aby dodać nowe słówko."
#user = current_user
#word = #user.words.build(word_params)
to:
#user = current_user
#word = #user.words.build(word_params)
authorize! :create, #word, :message => "Musisz się zalogować, aby dodać nowe słówko."
And it works fine. In the previous version variable #word was definied after authorize! method, so it doesn't work properly.

RSpec Controller tests fail for POST create

My program functions as expected, but there are problems in my RSpec controller test code. I need help troubleshooting the specs, which were created when I ran the scaffold generator. There are three "POST create with valid params" failures:
POST create
with valid params
creates a new Appointment (FAILED - 1)
assigns a newly created appointment as #appointment (FAILED - 2)
redirects to the created appointment (FAILED - 3)
Failures:
1) AppointmentsController POST create with valid params creates a new Appointment
Failure/Error: expect {
expected #count to have changed by 1, but was changed by 0
# ./spec/controllers/appointments_controller_spec.rb:90:in `block (4 levels) in <top (required)>'
2) AppointmentsController POST create with valid params assigns a newly created appointment as #appointment
Failure/Error: expect(assigns(:appointment)).to be_persisted
expected `#<Appointment id: nil, member_id: nil, trainer_id: nil, created_at: nil, updated_at: nil, date: "2020-01-02", starts_at: "2000-01-01 08:00:00", ends_at: "2000-01-01 09:00:00">.persisted?` to return true, got false
# ./spec/controllers/appointments_controller_spec.rb:99:in `block (4 levels) in <top (required)>'
3) AppointmentsController POST create with valid params redirects to the created appointment
Failure/Error: expect(response).to redirect_to(Appointment.last)
Expected response to be a <redirect>, but was <200>
# ./spec/controllers/appointments_controller_spec.rb:104:in `block (4 levels) in <top (required)>'
In the second failure, I notice there are nil values for appointment id, member and trainer, although I have valid factories for member and trainer. Tests for my member and trainer factories pass, and they work as expected. I assume the problem must be caused by the way I set up the "valid attributes" hash in the Controller spec, but I don't know what's wrong. Why are the POST create tests failing? What do I need to do to get them to pass?
Here's the code for the Appointments Controller RSpec:
require 'rails_helper'
RSpec.describe AppointmentsController, :type => :controller do
let(:valid_attributes) { {
'date' => '2020-01-02',
'starts_at' => '08:00:00',
'ends_at' => '09:00:00',
'member' => FactoryGirl.build(:member),
'trainer' => FactoryGirl.build(:trainer)
}
}
let(:invalid_attributes) { {
'date' => '2000-01-02',
'starts_at' => '06:00:00',
'ends_at' => '09:00:00',
'member' => FactoryGirl.build(:member),
'trainer' => FactoryGirl.build(:trainer)
}
}
let(:valid_session) { {
'date' => '2020-12-30',
'starts_at' => '15:00:00',
'ends_at' => '17:00:00',
'member' => FactoryGirl.build(:member),
'trainer' => FactoryGirl.build(:trainer)
}
}
describe "GET index" do
it "assigns all appointments as #appointments" do
appointment = Appointment.create! valid_attributes
get :index, {}, valid_session
expect(assigns(:appointments)).to eq([appointment])
end
end
describe "GET show" do
it "assigns the requested appointment as #appointment" do
appointment = Appointment.create! valid_attributes
get :show, {:id => appointment.to_param}, valid_session
expect(assigns(:appointment)).to eq(appointment)
end
end
describe "GET new" do
it "assigns a new appointment as #appointment" do
get :new, {}, valid_session
expect(assigns(:appointment)).to be_a_new(Appointment)
end
end
describe "GET edit" do
it "assigns the requested appointment as #appointment" do
appointment = Appointment.create! valid_attributes
get :edit, {:id => appointment.to_param}, valid_session
expect(assigns(:appointment)).to eq(appointment)
end
end
describe "POST create" do
describe "with valid params" do
it "creates a new Appointment" do
expect {
post :create, {:appointment => valid_attributes}, valid_session
}.to change(Appointment, :count).by(1)
save_and_open_page
end
it "assigns a newly created appointment as #appointment" do
post :create, {:appointment => valid_attributes}, valid_session
expect(assigns(:appointment)).to be_a(Appointment)
expect(assigns(:appointment)).to be_persisted
end
it "redirects to the created appointment" do
post :create, {:appointment => valid_attributes}, valid_session
expect(response).to redirect_to(Appointment.last)
end
end
describe "with invalid params" do
it "assigns a newly created but unsaved appointment as #appointment" do
post :create, {:appointment => invalid_attributes}, valid_session
expect(assigns(:appointment)).to be_a_new(Appointment)
end
it "re-renders the 'new' template" do
post :create, {:appointment => invalid_attributes}, valid_session
expect(response).to render_template("new")
end
end
end
describe "PUT update" do
describe "with valid params" do
let(:new_attributes) { {
'date' => '2020-01-02',
'starts_at' => '10:00:00',
'ends_at' => '12:00:00',
'member' => FactoryGirl.build(:member),
'trainer' => FactoryGirl.build(:trainer)
}
}
let(:invalid_attributes) { {
'date' => '2005-03-15',
'starts_at' => '04:00:00',
'ends_at' => '09:00:00',
'member' => FactoryGirl.build(:member),
'trainer' => FactoryGirl.build(:trainer)
}
}
it "updates the requested appointment" do
appointment = Appointment.create! valid_attributes
put :update, {:id => appointment.to_param, :appointment => new_attributes}, valid_session
appointment.reload
expect(controller.notice).to eq('Appointment was successfully updated.')
end
it "assigns the requested appointment as #appointment" do
appointment = Appointment.create! valid_attributes
put :update, {:id => appointment.to_param, :appointment => valid_attributes}, valid_session
expect(assigns(:appointment)).to eq(appointment)
end
it "redirects to the appointment" do
appointment = Appointment.create! valid_attributes
put :update, {:id => appointment.to_param, :appointment => valid_attributes}, valid_session
expect(response).to redirect_to(appointment)
end
end
describe "with invalid params" do
it "assigns the appointment as #appointment" do
appointment = Appointment.create! valid_attributes
put :update, {:id => appointment.to_param, :appointment => invalid_attributes}, valid_session
expect(assigns(:appointment)).to eq(appointment)
end
it "re-renders the 'edit' template" do
appointment = Appointment.create! valid_attributes
put :update, {:id => appointment.to_param, :appointment => invalid_attributes}, valid_session
expect(response).to render_template("edit")
end
end
end
describe "DELETE destroy" do
it "destroys the requested appointment" do
appointment = Appointment.create! valid_attributes
expect {
delete :destroy, {:id => appointment.to_param}, valid_session
}.to change(Appointment, :count).by(-1)
end
it "redirects to the appointments list" do
appointment = Appointment.create! valid_attributes
delete :destroy, {:id => appointment.to_param}, valid_session
expect(response).to redirect_to(appointments_url)
end
end
end
Here's the code for the Appointments Controller:
class AppointmentsController < ApplicationController
before_action :set_appointment, only: [:show, :edit, :update, :destroy]
# GET /appointments
# GET /appointments.json
def index
#appointments = Appointment.all
end
# GET /appointments/1
# GET /appointments/1.json
def show
end
# GET /appointments/new
def new
#appointment = Appointment.new
end
# GET /appointments/1/edit
def edit
end
# POST /appointments
# POST /appointments.json
def create
#appointment = Appointment.new(appointment_params)
respond_to do |format|
if #appointment.save
format.html { redirect_to #appointment, notice: 'Appointment was successfully created.' }
format.json { render :show, status: :created, location: #appointment }
else
format.html { render :new }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /appointments/1
# PATCH/PUT /appointments/1.json
def update
respond_to do |format|
if #appointment.update(appointment_params)
format.html { redirect_to #appointment, notice: 'Appointment was successfully updated.' }
format.json { render :show, status: :ok, location: #appointment }
else
format.html { render :edit }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /appointments/1
# DELETE /appointments/1.json
def destroy
#appointment.destroy
respond_to do |format|
format.html { redirect_to appointments_url, notice: 'Appointment was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_appointment
#appointment = Appointment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def appointment_params
params.require(:appointment).permit(:date, :starts_at, :ends_at, :member_id, :trainer_id)
end
end
The code for the Appointment Model:
class Appointment < ActiveRecord::Base
belongs_to :member
belongs_to :trainer
validates_date :date, :on => :create, :on_or_after => :today
validates_time :starts_at, :between => ['06:30', '21:00']
validates_time :starts_at, :after => :now, :if => :today_appointment #scopes validation to current day only
validates_time :ends_at, :after => :starts_at
validate :duration_of_appointment
validates :member, :trainer, presence: true
validates :starts_at, :ends_at, :overlap => {
:exclude_edges => ["starts_at", "ends_at"],
:scope => "date",
:scope => "starts_at",
:scope => "trainer_id"
}
validates :starts_at, :ends_at, :overlap => {
:exclude_edges => ["starts_at", "ends_at"],
:scope => "member_id"
}
private
def today_appointment
Date.current == self.date
end
def duration_of_appointment
length = (ends_at - starts_at) / 60
return if length.between?(30, 120) # stops validation if length falls between the two integers
errors.add(:base, 'Duration must be between 30 and 120 minutes')
end
end
You shouldn't provide a built instance of Member and Trainer to controller. Instead, create Member and Trainer, and pass their ids as member_id,
trainer_id in valid_attributes hash.
First, create needed trainer and member:
before :each do
#trainer = FactoryGirl.build(:trainer)
#member = FactoryGirl.build(:member)
end
Then use their ids in your hash:
let(:valid_attributes) { {
'date' => '2020-01-02',
'starts_at' => '08:00:00',
'ends_at' => '09:00:00',
'member_id' => #member.id,
'trainer_id' => #trainer.id
}
In your code, you didn't even create them, you've only built them, but only changing build(:trainer) to create(:trainer) won't work in your case.

Rspec - controller test error - Paperclip::AdapterRegistry::NoHandlerError: No handler found for "#<File:0x531beb0>"

I asked about my Rspec test as follow.
Rspec - RuntimeError: Called id for nil, which would mistakenly be 4
On the same code (Rspec test for "items_controller.rb"), I am trying to make the test for "PUT update". However I got the error "Paperclip::AdapterRegistry::NoHandlerError: No handler found for "#".
My Rspec test is as follow. Honestly, I guess that the cause of this fail is ""photo" => File.new(Rails.root + 'app/assets/images/rails.png')" on "let(:valid_attributes)". However, I tried several ways but I couldn't fix.
By the way, my rails version is "Rails 3.2.14". Then I tried following post, but also couldn't.
Can't figure out what's causing my tests to fail
The error is as follows.
......F....
Failures:
1) ItemsController PUT update could not update successfully
Failure/Error: put :update, {:id => item.to_param, :item => valid_attributes}, valid_session
Paperclip::AdapterRegistry::NoHandlerError:
No handler found for "#<File:0x5d4c548>"
# ./app/controllers/items_controller.rb:110:in `block in update'
# ./app/controllers/items_controller.rb:108:in `update'
# ./spec/controllers/items_controller_spec.rb:95:in `block (3 levels) in <top (required)>'
Finished in 1.75 seconds
11 examples, 1 failure
Failed examples:
rspec ./spec/controllers/items_controller_spec.rb:91 # ItemsController PUT update could not update successfully
Randomized with seed 40912
My Rspec test is as follows.
require 'spec_helper'
require 'date'
describe ItemsController do
let(:valid_attributes) { {
"days" => "1",
"hours" => "1",
"minutes" => "1",
"name"=>"HogeHoge" ,
"category" => "Gift",
"min_bid_price" => "100.0",
"description" => "HogeHoge",
"photo" => File.new(Rails.root + 'app/assets/images/rails.png')
} }
let(:valid_session) { {} }
it "returns http success" do
get "index"
response.should be_success
end
it "returns http success" do
get "new"
response.should be_success
end
describe "POST create" do
it "" do
#declare the objects and stubs
current_user = User.new(id:'1')
current_user.save
#"current_user=(user)" function on controller
controller.current_user = current_user
#auction
auction = Auction.new(id:'1',highest_bid_id:'1', extend_bit:'1')
auction.save
Auction.stub(:find_by_id).and_return(auction)
#bid
bid = Bid.new(auction_id:'1',amount:'150.0')
bid.save
Bid.stub(:find_by_id).and_return(bid)
#item
item = Item.new(id:'1',auction_id:'1',min_bid_price:'100.0')
item.save
Item.stub(:find_by_id).and_return(item)
date = DateTime.now
post :create, {:item => {'id' => '2','days'=>'1','hours'=>'1','minutes'=>'1','created_at'=>date}}
response.should be_success
end
end
describe "GET index" do
it "assigns all items as #items" do
item = Item.create! valid_attributes
get :index, {}, valid_session
assigns(:items).should eq([item])
end
end
describe "GET show" do
it "assigns the requested item as #item" do
item = Item.create! valid_attributes
get :show, {:id => item.to_param}, valid_session
assigns(:item).should eq(item)
end
end
describe "GET new" do
it "assigns a new item as #item" do
get :new, {}, valid_session
assigns(:item).should be_a_new(Item)
end
end
describe "GET edit" do
it "assigns the requested item as #item" do
item = Item.create! valid_attributes
get :edit, {:id => item.to_param}, valid_session
assigns(:item).should eq(item)
end
end
describe "PUT update" do
it "could not update successfully" do
item = Item.create! valid_attributes
# Trigger the behavior that occurs when invalid params are submitted
Item.any_instance.stub(:save).and_return(false)
put :update, {:id => item.to_param, :item => valid_attributes}, valid_session
assigns(:item).should eq(item)
response.should redirect_to(#item)
end
it "could not update successfully" do
item = Item.create! valid_attributes
# Trigger the behavior that occurs when invalid params are submitted
Item.any_instance.stub(:save).and_return(false)
put :update, {:id => item.to_param, :item => { }}, valid_session
response.should render_template("edit")
end
end
describe "DELETE destroy" do
it "destroys the requested item" do
item = Item.create! valid_attributes
expect {
delete :destroy, {:id => item.to_param}, valid_session
}.to change(Item, :count).by(-1)
end
it "redirects to the items list" do
item = Item.create! valid_attributes
delete :destroy, {:id => item.to_param}, valid_session
response.should redirect_to(items_url)
end
end
end
My "items_controller.rb" is as follw.
require 'timers'
class ItemsController < ApplicationController
#instance of current user
def current_user=(user)
#current_user ||= user
end
def extendtimer
Auction.find_by_id(#auction_id).update_attributes(:extend_bit => 0)
#exp = Auction.find_by_id(#auction_id).exp_time + 2.minutes
Auction.find_by_id(#auction_id).update_attributes(:exp_time => #exp)
#min = Item.find_by_id(#item_id).minutes + 2
Item.find_by_id(#item_id).update_attributes(:minutes => #min)
#timer2 = Timers.new
#extend_timer = #timer2.after(120){ buy }
#timer2.wait
end
def buy
if Auction.find_by_id(#auction_id).extend_bit == 1
extendtimer
else
if Auction.find_by_id(#auction_id).highest_bid_id != 0
Item.find_by_auction_id(#auction_id).update_attributes(:sold => 1, :sold_to => Bid.find_by_id(Auction.find_by_id(#auction_id).highest_bid_id).user_id )
MyMailer.auction_winner_email(Auction.find_by_id(#auction_id)).deliver
else
Item.find_by_auction_id(#auction_id).update_attributes(:sold => 0, :sold_to => 0 )
MyMailer.no_bids_email(Auction.find_by_id(#auction_id)).deliver
end
#t1.join
end
end
def index
#items = Item.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #items }
end
end
# GET /items/1
# GET /items/1.json
def show
#item = Item.find(params[:id])
respond_to do |format|
#format.html # show.html.erb
format.html { render layout: (request.headers["X-Requested-With"] != 'XMLHttpRequest') }
format.json { render json: #item }
end
end
# GET /items/new
# GET /items/new.json
def new
#item = Item.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #item }
end
end
# GET /items/1/edit
def edit
#item = Item.find(params[:id])
end
# POST /items
# POST /items.json
def create
#item = Item.new(params[:item])
#item.user_id = current_user.id
respond_to do |format|
if #item.save
format.html { redirect_to #item, notice: 'Item was successfully created.' }
format.json { render json: #item, status: :created, location: #item }
else
format.html { render action: "new" }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
#elapsed_seconds =(((params[:item][:days].to_i * 24)+params[:item][:hours].to_i)*60+params[:item][:minutes].to_i)*60
#auction = Auction.create(:item_id => #item.id, :highest_bid_id => 0, :exp_time => #item.created_at+ #elapsed_seconds.seconds, :suspend => 0, :user_id => #current_user.id, :extend_bit => 0 )
#item.update_attributes(:auction_id => #auction.id)
#item_id = #item.id
#auction_id = #auction.id
#t1 = Thread.new{
#timer = Timers.new
#bid_timer = #timer.after(#elapsed_seconds){
if Auction.find_by_id(#auction_id).suspend != 1
buy
end
}
#timer.wait
}
end
# PUT /items/1
# PUT /items/1.json
def update
#item = Item.find(params[:id])
respond_to do |format|
if #item.update_attributes(params[:item])
format.html { redirect_to #item, notice: 'Item was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /items/1
# DELETE /items/1.json
def destroy
#item = Item.find(params[:id])
#item.destroy
respond_to do |format|
format.html { redirect_to items_url }
format.json { head :no_content }
end
end
end
I would like to have someone's advice. Thank you in advance.
Try using Rack::Test::UploadedFile instead of File.new
require 'rack/test'
Rack::Test::UploadedFile.new('fixtures/test_file.png', 'image/png')
im pretty sure your problem is with the form_for in the view,
try something like this:
<%= form_for #restaurante, :html => { :multipart => true } do |form| %>
Nome:<%= form.text_field :nome%>
Endereço:<%= form.text_field :endereco %>
Especialidade:<%= form.text_field :especialidade %>
Foto:<%= form.file_field :foto %>
<%= form.submit 'create'%>
<% end %>
Make sure it's multipart/form-data in the test.
I have a helper method for this.
module Support
module Acceptance
module ClassMethods
def multipart_form_data!
header 'Accept', 'application/json'
header 'Content-Type', 'multipart/form-data'
end
end
end
end

Rspec nested controller create method does not increase count by 1

I am testing an Invoice model (a Client has many invoices, an Invoice belongs to a Client) and trying to check whether the create method works.
This is what I have come up with:
before do
#valid_invoice = FactoryGirl.create(:invoice)
#valid_client = #valid_invoice.client
end
it "creates a new Invoice" do
expect {
post :create, { invoice: #valid_client.invoices.build(valid_attributes), client_id: #valid_client.to_param }
}.to change(Invoice, :count).by(1)
end
This is my invoice factory:
FactoryGirl.define do
factory :invoice do
association :client
gross_amount 3.14
net_amount 3.14
number "MyString"
payment_on "2013-01-01"
vat_rate 0.19
end
end
This is the create method in the invoices_controller:
def create
#client = Client.find(params[:client_id])
#invoice = #client.invoices.build(params[:invoice])
respond_to do |format|
if #invoice.save
format.html { redirect_to([#invoice.client, #invoice], :notice => 'Invoice was successfully created.') }
format.json { render :json => #invoice, :status => :created, :location => [#invoice.client, #invoice] }
else
format.html { render :action => "new" }
format.json { render :json => #invoice.errors, :status => :unprocessable_entity }
end
end
end
And these are the valid attributes, ie the attributes needed for an invoice to be created successfully:
def valid_attributes
{
gross_amount: 3.14,
net_amount: 3.14,
number: "MyString",
payment_on: "2013-01-01",
vat_rate: 0.19
}
end
These are all valid. Maybe the client_id is missing?
It is only telling me that the count did not change by one - so I am not sure what the problem is. What am I doing wrong?
#gregates - Your answer was right, why did you remove it? :-) Post it again and I will check it as best answer.
This is the solution:
post :create, { invoice: valid_attributes, client_id: #valid_client.to_param }, valid_session
instead of
post :create, { invoice: #valid_client.invoices.build(valid_attributes), client_id: #valid_client.to_param }
in the test.
Also, I had to change the number in the valid_attributes. Debugging every single validation showed me that it was the same as in the factory - but must instead be unique. This solved it for me! Thanks for everyone's help!

How would I test a param is getting modified in a RSpec controller test?

I am setting a user through modifying the params instead of creating a hidden_field in the form. As far as I understand, this is a more secure way of handling mass-assignment.
def update
#exercise = Exercise.find(params[:id])
#this is the important part
if params[:exercise][:log_entries_attributes].present?
params[:exercise][:log_entries_attributes].each do |value|
value[1].merge!(:user_id => current_user.id)
end
end
#end the important part
respond_to do |format|
if #exercise.update_attributes(params[:exercise])
format.html { redirect_to_back_or_default #exercise, notice: "Exercise was successfully updated." }
format.mobile { redirect_to #exercise, notice: 'Exercise was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.mobile { redirect_to #exercise, notice: "#{#exercise.errors.full_messages.to_sentence}" }
format.json { render json: #exercise.errors, status: :unprocessable_entity }
end
end
end
In my spec I have the following:
describe "with log_entry_attributes" do
it "updates log_entries_attributes and sets user" do
exercise = FactoryGirl.create(:exercise)
log_entry = FactoryGirl.build(:log_entry)
exercise.log_entries << log_entry
exercise.save
controller.stub(:current_user).and_return(#user)
put :update, :id => exercise.id, :exercise => FactoryGirl.build(:exercise, "log_entries_attributes" => {":0" => {"reps" => "5", "weight" => "5"}}).attributes.symbolize_keys
assigns(:exercise).log_entries.first.user.should eq(#user)
end
end
I get undefined method user for nil:NilClass. I think I know why I get undefined method user. There's just no way to get the association through assigns. I'm not sure how to test that the user_id is being set properly through the current_user. Any help?
Work with mocked object:
exercise = double "exercise"
Exercise.should_receive(:find).and_return(exercise)
and test with:
exercise.should_receive(:update_attributes).with(correct_params)

Resources