Ruby on rails 设计、Rspec、用户期望
显然,我正在使用Desive进行身份验证,我试图做的是测试是否在用户对象上调用了一个方法。因此,我的规格如下所示:Ruby on rails 设计、Rspec、用户期望,ruby-on-rails,rspec,devise,Ruby On Rails,Rspec,Devise,显然,我正在使用Desive进行身份验证,我试图做的是测试是否在用户对象上调用了一个方法。因此,我的规格如下所示: it "should retrieve something for user" do @user = Factory.create(:user) sign_in @user @user.expects(:something) get :manage end 我的问题是,除非我: it "should retrieve something for user" do
it "should retrieve something for user" do
@user = Factory.create(:user)
sign_in @user
@user.expects(:something)
get :manage
end
我的问题是,除非我:
it "should retrieve something for user" do
@user = Factory.create(:user)
sign_in @user
controller.stubs(:current_user).returns @user
@user.expects(:something)
get :manage
end
如果sign_in@user是一个designe测试助手,那么在控制器上假装当前用户调用似乎很愚蠢。在调试器中挖掘之后,如果没有伪造当前用户,@user确实被返回,那么它也会出现,因此我不确定为什么没有达到预期
Ideas?当前用户在存储到会话中之前被序列化;很可能,对于ActiveRecord用户模型,它存储的是用户id: 这意味着当控制器再次获取用户时: 它在会话中查找用户id,并从数据库中重新获取用户 这意味着控制器中的#current_User返回的User对象与测试中传入的@User#sign_不同,因此一个对象的存根和期望不会附加到另一个对象 我没有广泛使用Deave/Warden,但我很确定这就是发生的事情。您可以尝试在两个实例上打印出#object_id以确认这一点 挑剔的语义更新2014年2月: 在控制器上存根
#当前用户
是一种很好的方法,这取决于您对被测系统(SUT)的“边界”(即控制器)的定义。假设#current_user
方法是由designe定义的,并由designe混合到控制器中,您可以认为#current_user
是SUT的外部用户,因此存根是公平的
您也可以存根Desive正在访问的底层(ActiveRecord),比如存根User.find
,以返回@User
对象。这意味着您的规范正在测试您的操作实现以及#current_user
的designe实现,因此如果以后更改了其中任何一项,规范都将失败
假设Deviate使用
User.find(args)
,并假设您将该方法存根,然后Deviate的更高版本更改为使用User.where(args).first()
-您的代码没有更改,但基础库已更改,并且您的规范失败。大致考虑一下这个想法,有时您可能会喜欢这种行为(例如,考虑用stubingNet::HTTP
方法来模拟原始HTTP响应,以便以后可以交换HTTP库),有时您不喜欢(也许这个设计问题算作一个问题).经过昨晚的挖掘,看来你是对的!感谢您提供的信息。经过数小时的搜索,终于找到了解决方案。。非常感谢。