我是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 的方法无法从后规范模型中检索出来?
答案 0 :(得分:0)
你是绝对正确的 - 因为你在post_spec.rb中定义了相关的post方法,所以无法从vote_spec.rb中调用它。
您有几个选项:您可以复制关联的post方法并将其放在vote_spec.rb中,或者您可以创建一个spec帮助文件,您可以在其中定义associated_post一次并将其包含在vote_spec.rb和post_spec.rb中。希望有所帮助!