dimanche 29 mars 2015

RSPEC test NAME ERROR - Undefined Local variable or method

I'm a beginner in ruby on rails and programming in general. I have an assignment where I have to test my rspec model Vote, and as per instructions the test should pass.


When I run rspec spec/models/vote_spec.rb on the console, I receive the following error:



.F

Failures:

1) Vote after_save calls `Post#update_rank` after save
Failure/Error: post = associated_post
NameError:
undefined local variable or method `associated_post' for #<RSpec::ExampleGroups::Vote::AfterSave:0x007f9416c791e0>
# ./spec/models/vote_spec.rb:22:in `block (3 levels) in <top (required)>'

Finished in 0.28533 seconds (files took 2.55 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./spec/models/vote_spec.rb:21 # Vote after_save calls `Post#update_rank` after save


Here is my vote_spec code:



require 'rails_helper'
describe Vote do
describe "validations" do
describe "value validation" do
it "only allows -1 or 1 as values" do

up_vote = Vote.new(value: 1)
expect(up_vote.valid?).to eq(true)

down_vote = Vote.new(value: -1)
expect(down_vote.valid?).to eq(true)

invalid_vote = Vote.new(value: 2)
expect(invalid_vote.valid?).to eq(false)

end
end
end

describe 'after_save' do
it "calls `Post#update_rank` after save" do
post = associated_post
vote = Vote.new(value: 1, post: post)
expect(post).to receive(:update_rank)
vote.save
end
end
end


And here is my post_spec code:



require 'rails_helper'

describe Post do
describe "vote method" do


before do
user = User.create
topic = Topic.create
@post = associated_post
3.times { @post.votes.create(value: 1) }
2.times { @post.votes.create(value: -1) }
end

describe '#up_votes' do
it "counts the number of votes with value = 1" do
expect( @post.up_votes ).to eq(3)
end
end

describe '#down_votes' do
it "counts the number of votes with value = -1" do
expect( @post.down_votes ).to eq(2)
end
end

describe '#points' do
it "returns the sum of all down and up votes" do
expect( @post.points).to eq(1) # 3 - 2
end
end
end

describe '#create_vote' do
it "generates an up-vote when explicitly called" do
post = associated_post
expect(post.up_votes ).to eq(0)
post.create_vote
expect( post.up_votes).to eq(1)
end
end

end

def associated_post(options = {})
post_options = {
title: 'Post title',
body: 'Post bodies must be pretty long.',
topic: Topic.create(name: 'Topic name',description: 'the description of a topic must be long'),
user: authenticated_user
}.merge(options)

Post.create(post_options)
end

def authenticated_user(options = {})
user_options = { email: "email#{rand}@fake.com", password: 'password'}.merge(options)
user = User.new( user_options)
user.skip_confirmation!
user.save
user
end


I'm not sure if providing the Post and Vote models code is necessary. Here is my Post model:



class Post < ActiveRecord::Base
has_many :votes, dependent: :destroy
has_many :comments, dependent: :destroy
belongs_to :user
belongs_to :topic

default_scope { order('rank DESC')}


validates :title, length: { minimum: 5 }, presence: true
validates :body, length: { minimum: 20 }, presence: true
validates :user, presence: true
validates :topic, presence: true



def up_votes
votes.where(value: 1).count
end

def down_votes
votes.where(value: -1).count
end


def points
votes.sum(:value)
end

def update_rank
age_in_days = ( created_at - Time.new(1970,1,1)) / (60 * 60 * 24)
new_rank = points + age_in_days

update_attribute(:rank, new_rank)
end



def create_vote
user.votes.create(value: 1, post: self)
# user.votes.create(value: 1, post: self)
# self.user.votes.create(value: 1, post: self)
# votes.create(value: 1, user: user)
# self.votes.create(value: 1, user: user)

# vote = Vote.create(value: 1, user: user, post: self)
# self.votes << vote
# save
end

end


and the Vote model:



class Vote < ActiveRecord::Base
belongs_to :post
belongs_to :user

validates :value, inclusion: { in: [-1, 1], message: "%{value} is not a valid vote."}

after_save :update_post



def update_post
post.update_rank
end

end


It seems like in the spec vote model, the method assosicated_post can't be retrieved from the post spec model?


Aucun commentaire:

Enregistrer un commentaire