RSPEC 测试名称错误 - 未定义的局部变量或方法

RSPEC test NAME ERROR - Undefined Local variable or method

我是 ruby 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 和投票模型代码。 这是我的 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 无法从 post规格型号?

您完全正确 - 因为您在 post_spec.rb 内部定义了关联的 post 方法,所以无法从 vote_spec.rb.

内部调用它

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