我正在使用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.
...
答案 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将解决您的问题