2014-02-05 86 views
0

我是Rspec的新手,我正在为旧项目进行测试。我遇到了设置变量的问题。基本上,我的用户对象受到之前测试中的操作的影响。 我有一个简单的用户工厂:由于之前的测试,Rspec单元测试失败

FactoryGirl.define do 
    factory :user do 
     first_name 'Bob' 
     last_name 'Shabbadoo' 
     office 
     login 'lurker48' 
     email '[email protected]' 
     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

当你建立新的用户对象时,工厂女孩分配给它的密码给定的字符串(这是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运行每个你建立新的对象,从而创建独立但相同的字符串实例时阻止:据

factory :user do 
    first_name { 'Bob' } 
    last_name { 'Shabbadoo' } 
    ... 
+0

我记得注明HAS_ONE协会名称为这个对象调用的工厂,所以这两个对象应该是不同。 – BroiSatse

+0

是的,你是对的。我不应该担心这种关联,因为我不会像我那样操纵信息。我使用+ =语法,因为这只会在需要时创建一个新字符串。 – BrandonRachal