RSPEC测试NAME ERROR - 未定义的局部变量或方法

时间:2015-03-29 14:45:58

标签: ruby-on-rails ruby ruby-on-rails-4 testing rspec

我是ruby on rails和一般编程的初学者。 我有一个任务,我必须测试我的rspec模型投票,并按照说明测试应该通过。

当我在控制台上运行rspec spec / models / vote_spec.rb时,收到以下错误:

.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

这是我的vote_spec代码:

       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

这是我的post_spec代码:

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

我不确定是否需要提供Post和Vote模型代码。 这是我的Post模型:

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

和投票模型:

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

似乎在规范投票模型中, assosicated_post 的方法无法从后规范模型中检索出来?

1 个答案:

答案 0 :(得分:0)

你是绝对正确的 - 因为你在post_spec.rb中定义了相关的post方法,所以无法从vote_spec.rb中调用它。

您有几个选项:您可以复制关联的post方法并将其放在vote_spec.rb中,或者您可以创建一个spec帮助文件,您可以在其中定义associated_post一次并将其包含在vote_spec.rb和post_spec.rb中。希望有所帮助!