我是Rspec的新手,我正在为一个旧项目进行测试。我在设置变量方面遇到了问题。基本上,我的User对象受先前测试中的操作的影响。 我有一个简单的用户工厂:
FactoryGirl.define do
factory :user do
first_name 'Bob'
last_name 'Shabbadoo'
office
login 'lurker48'
email 'test.user@test.com'
password 'TestWhatNots#21'
password_confirmation{|u| u.password}
end
end
然后我进行了实际的rspec测试。
require "spec_helper"
describe User do
it 'has a valid factory' do
FactoryGirl.build(:user).should be_valid
end
describe '#password' do
it "cannot contain the word 'password'" do
valid_user = FactoryGirl.build(:user)
valid_user.password << "password"
valid_user.password_confirmation = valid_user.password
valid_user.should_not be_valid
end
it "cannot contain the users last_name" do
valid_user = FactoryGirl.build(:user)
valid_user.password << valid_user.last_name
valid_user.password_confirmation = valid_user.password
valid_user.should_not be_valid
end
it "cannot contain the users first_name" do
valid_user = FactoryGirl.build(:user)
valid_user.password << valid_user.first_name
valid_user.password_confirmation = valid_user.password
valid_user.should be_valid
end
end
end
我故意使“无法包含用户first_name”测试失败 正如我所料,我得到了这个:
User
has a valid factory
#password
cannot contain the word 'password'
cannot contain the users last_name
cannot contain the users first_name (FAILED - 1)
但是当我仔细查看密码时,它看起来像这样:
TestWhatNots#21passwordShabbadooBob
为什么先前测试中的操作会污染信息?
答案 0 :(得分:0)
当您构建新的用户对象时,工厂女孩会将其密码分配给给定字符串(它是String类的实例)。每次执行此操作时,您的用户密码都指向该对象 - 如果您构建两个用户,则他们的密码不仅相同 - 它们是相同的对象。
使用<<
方法更改此对象,因此您正在更改此工厂已经或将要创建的所有对象的密码值。
u1 = FactoryGirl.build(:user)
u2 = FactoryGirl.build(:user)
u1.password.object_id == u2.password.object_id #=> true!
解决方案:
选项1.不要修改对象,而是分配新的字符串对象:
valid_user.password += valid_user.first_name
选项2.将所有值包装在一个块中。这将强制FactoryGirl在每次构建新对象时运行块,从而创建单独但相同的String实例:
factory :user do
first_name { 'Bob' }
last_name { 'Shabbadoo' }
...