访问模型的字段

时间:2014-04-05 02:14:46

标签: ruby-on-rails ruby rspec

我正在使用rails开始我的第一步并正在阅读M.Hartl的教程。我正在尝试编写一些简单的测试来检查删除用户时删除以下关系

describe "deleting user should delete relationship" do
  before do
    other_user.destroy
  end

  expect(@user.name).to eq("Tom") # undefined method name
  expect(@user.followers).to include(other_user) # undefined method followers
  its(:followers) { should_not include(other_user) } # this works
end

为什么没有定义@user.name@user.followers?我怎么才能访问它?我希望至少名称能够存在,因为它的用户模型的属性......它是否以某种方式私有,我需要编写访问器才能访问它?关注者也一样..我是否必须编写单独的方法来返回用户的关注者?

用户模型如下所示:

class User < ActiveRecord::Base
  has_many :microposts, dependent: :destroy
  has_many :relationships, foreign_key: "follower_id", dependent: :destroy
  has_many :followed_users, through: :relationships, source: :followed
  has_many :reverse_relationships, foreign_key: "followed_id", class_name: "Relationship", dependent: :destroy
  has_many :followers, through: :reverse_relationships, source: :follower # we could omit source in this case since, in the case of a :followers attribute, Rails will singularize “followers” and automatically look for the foreign key follower_id in this case.
  ...

2 个答案:

答案 0 :(得分:3)

您不能在测试之外使用期望 - 您需要将它们包装在:

it 'name is Tom' do
  expect(@user.name).to eq 'Tom'
end

it 'is followed by deleted user' do
  expect(@user.followers).to include(other_user)
end

its方法是一个方便的捷径:

its(:attribute) { should be_present }    # test name: Its attribute should be present

与(更好的测试名称除外)相同:

it 'has present attribute' do            # test name: It has present attribute
  subject.attribute.should be_present
end

请注意,您需要在测试套件中定义subject才能使用第二种形式。如果您定义了主题,则应使用它而不是实例变量(这样您就可以在不更改所有测试的情况下轻松更改主题)。所以你的测试应该是这样的:

its(:name) { should eq 'Tom' }
its(:followers) { should_not include(other_user) }

它不能按照您编写它的方式工作的原因是@user是一个实例变量,您试图在类的上下文中执行它。这自然会返回“nil”,因为该类没有定义这样的变量。

答案 1 :(得分:0)

你必须嘲笑你的对象@user。简单的方法是

let(@user){ User.new(name: "Foo") }

这会将新用户安装到@user。 我更喜欢使用FactoryGirl来做到这一点。但User.new将解决您的问题