2010-07-22 73 views
0

我正在测试一个简单的密码重置动作,并希望RSpec的lambda的“更改”匹配器。但它不适用于此控制器操作。没有匹配器,一切正常。这是规格:带和不带lambda +的控制器规格“应该改变”

describe "#update" do 
it "Updates the password and resets the token" do 
    @user = Factory :user 
    getter = lambda{ 
    get :edit, :id => @user.perishable_token, :user => {:password_confirmation => "new_password", 
                 :password => "new_password"} 
    @user.reload 
    } 
    getter.should change(@user, :password) 
    getter.should change(@user, :perishable_token) 
end 

it "Updates the password and resets the token" do 
    @user = Factory :user 
    old_password = @user.password 
    old_token = @user.perishable_token 
    get :edit, :id => @user.perishable_token, :user => {:password_confirmation => "new_password", 
                 :password => "new_password"}   
    @user.reload.password.should != old_password 
    @user.perishable_token.should != old_token 
end 
end 

第二个块的作品,第一个没有。我试图打印lambda内的值,他们确实没有改变。

非常感谢你对这个问题的任何想法!

回答

0

因此,事实证明,改变匹配器调用proc。所以这不是问题。但是,我打电话编辑而不是更新。所以没有什么应该改变。另外密码只存在于密码刚刚设置的用户对象上,以及由于未保存明文密码而未从数据库中检索的用户对象。下面是现在的工作代码:

describe "#update" do 
it "Updates the password and resets the token" do 
    @user = Factory.create :user 
    getter = lambda{ 
    post :update, :id => @user.perishable_token, :user => {:password_confirmation => "new_password", 
                  :password => "new_password"} 
    @user.reload 
    } 
    getter.should change(@user, :crypted_password) 
    getter.should change(@user, :perishable_token) 
end 
end 

我认为它会变成是一个愚蠢的错误,但两人在一个...

0

您需要使用call才能在第一个示例中实际执行lambda。您将lambda分配给getter,但从不执行getter.call来实际执行lambda并获得您的结果。

+0

拉姆达似乎已经得到执行。我在lambda定义和期望之间尝试了“getter.call”,没有任何改变。然后我试着“getter.call.should改变(@user,:password)”,但得到一个错误,说用户没有方法'调用'。所以我得出结论,lamda返回了最后一条声明,即@ user.reload。这得到了证实,在lamda的末尾添加了一个print语句,并且错​​误消息更改为未定义的方法'call'for nil。 – ajmurmann 2010-07-22 14:50:05