1

我对投票模型进行了以下 Rspec 测试,其中包括自定义验证,以确保您无法对自己的内容进行投票,如下所示。当规范中的其他测试通过时,为什么只有 2 个测试失败并出现 nilclass 错误,我对此感到困惑。

@vote 必须为零,但为什么其他测试没有因相同的错误而失败?

投票.rb

validates :ensure_not_author

def ensure_not_author 
    votable = self.votable_type.downcase
    errors.add(:user_id, "You can't vote on your own content.") if self.votable.user_id == self.user_id
  end

工厂

factory :answer do
    user_id :user
    question_id :question
    body "you need to change your grip"
    votes_count 0
    correct false
  end

  factory :vote do
    user_id :user
    votable_id :answer
    votable_type "Answer"
    value 1
    points 5
  end

factory :user do |u|
    u.sequence(:email) {|n| "test#{n}@hotmail.com"}
    u.sequence(:username) {|n| "tester#{n}" }
    u.password "password"
    u.password_confirmation "password" 
    u.remember_me true
    u.reputation 200
  end

vote_spec.rb

require "spec_helper"

describe Vote do
  before(:each) do
    @user2 = FactoryGirl.create(:user)
    @user = FactoryGirl.create(:user)
    @answer = FactoryGirl.create(:answer, user_id: @user)
    @vote = Vote.create(user_id: @user2.id, value: 1, points: 5, votable_id: @answer.id, votable_type: "Answer")
  end

  subject { @vote }

  it { should respond_to(:user_id) }
  it { should respond_to(:votable_id) }
  it { should respond_to(:votable_type) }
  it { should respond_to(:value) }
  it { should respond_to(:points) }

   describe 'value' do
     before { @vote.value = nil }
     it { should_not be_valid }
   end

   describe "user_id" do
      before { @vote.user_id = nil }
       it { should_not be_valid }
     end

   describe "votable_id" do
     before { @vote.votable_id = nil }
     it { should_not be_valid }
   end

   describe "votable type" do
      before { @vote.votable_type = nil }
      it { should_not be_valid }
   end

   describe "vote value" do
      before { @vote.value = 5 }
      it { should_not be_valid }
   end
end

失败:

1) Vote votable_id 
     Failure/Error: it { should_not be_valid }
     NoMethodError:
       undefined method `user_id' for nil:NilClass
     # ./app/models/vote.rb:17:in `ensure_not_author'
     # ./spec/models/vote_spec.rb:25:in `block (3 levels) in <top (required)>'

  2) Vote votable type 
     Failure/Error: it { should_not be_valid }
     NoMethodError:
       undefined method `downcase' for nil:NilClass
     # ./app/models/vote.rb:16:in `ensure_not_author'
     # ./spec/models/vote_spec.rb:35:in `block (3 levels) in <top (required)>'
4

1 回答 1

2

您的验证器ensure_not_author依赖Vote#votable_typeVote#votable运行良好。当您测试 的有效性时@vote,将测试此验证器。

但是,在您的"votable_id"测试用例中,您设置votable_idnil. 稍后当您使用 测试@vote的有效性时should_not be_validensure_not_author会调用并失败,self.votable.user_id因为 ActiveRecord 将查询Votablewith votable_id

同样,您的"votable type"测试用例失败,self.votable_type.downcase因为您设置votable_typenil

在向验证器发送消息之前,您应该检查验证器中属性的可用性。或者之前编写其他验证器来检查它们ensure_not_author

于 2013-06-20T13:48:14.050 回答