ruby on rails - RSpec test fails when checking if user.should be_valid -
i'm new testing, , can't figure out why fails:
i have test
require 'spec_helper' require 'cancan/matchers' describe user subject(:user) { user.create!(email: 'test@test.com', password: '12345678', password_confirmation: '12345678', goal_id: '1', experience_level_id: '1', gender: 'female') } "should valid name, goal, password, password_confirmation, experience_level, , gender" user.should be_valid end
i think should pass. can create user through site front end, i'm getting following fail message:
1) user should valid name, goal, password, password_confirmation, experience_level, , gender failure/error: subject(:user) { user.create!(email: 'test@test.com', password: '12345678', password_confirmation: '12345678', goal_id: '1', experience_level_id: '1', gender: 'female') } runtimeerror: called id nil, mistakenly 4 -- if wanted id of nil, use object_id # ./app/models/user.rb:32:in `add_initial_program' # ./spec/models/user_spec.rb:5:in `block (2 levels) in <top (required)>' # ./spec/models/user_spec.rb:13:in `block (2 levels) in <top (required)>'
edit:
adding user model:
class user < activerecord::base devise :database_authenticatable, :registerable, :omniauthable, :recoverable, :rememberable, :trackable, :validatable, :token_authenticatable before_save :ensure_authentication_token attr_accessible :email, :password, :password_confirmation, :remember_me, :goal_id, :experience_level_id, :gender, :role, :name, :avatar, :remote_avatar_url, :authentication_token, :measurement_units validates :goal_id, presence: :true validates :experience_level_id, presence: :true validates :gender, presence: :true before_create :add_initial_program, :assign_initial_settings protected def add_initial_program prog_id = program.for_user(self).first.id self.user_programs.build( :cycle_order => 1, :group_order => 1, :workout_order => 1, :program_id => prog_id) end
line 32 is: prog_id = program.for_user(self).first.id
and method being referenced:
def self.for_user(user) where(:goal_id => user.goal_id, :experience_id => user.experience_level_id, :gender => user.gender) end
prog_id = program.for_user(self).first.id
means, "get id of first program associated user". based on see, can infer program.for_user(self).first
nil, , id
method being called on nil. sure there program model saved in test db associated user create in test? doesn't appear creating model anywhere, and, based on code, essential there associated program in place before try create user.
edit:
you can initialize program in subject block so:
subject(:user) program.create!(#whatever attributes appropriate) user.create!(email: 'test@test.com', password: '12345678', password_confirmation: '12345678', goal_id: '1', experience_level_id: '1', gender: 'female') end
the last value in block relevant return value subject block, long block returns user model, things should fine, if have more 1 statement in block. this, me, cleanest initialization option can changing tests alone, because it's clear user , program tightly bound together, such have valid user first must have associated program. think better have logic in user model creates program if 1 doesn't exist (you might want check out query method #first_or_create), multiple statements inside block should work now.
Comments
Post a Comment