Rails response.should be_success永远不会成真
我正在关注Michael Hartl关于Ruby on Rails的优秀教程。 我试图理解ActionDispatch :: Response的工作方式。 这源于第9章的练习9(Rails版本3.2.3)。
特别要求我们确保管理员用户无法User#destroy
自己。 我知道如何做到这一点,但由于我正在尝试遵循TDD方法,我首先编写测试。
这是我测试中的相关片段:
describe "authorization" do describe "as non-admin user" do let(:admin) {FactoryGirl.create(:admin)} let(:non_admin) {FactoryGirl.create(:user)} before{valid_signin non_admin} describe "submitting a DELETE request to the Users#destroy action" do before do delete user_path(admin) #puts response.message puts response.succes? end specify{ response.should redirect_to(root_path) } specify{ response.should_not be_success } end end #Exercise 9.6-9 prevent admin from destroying himself describe "as admin user" do let(:admin){FactoryGirl.create(:admin)} let(:non_admin){FactoryGirl.create(:user)} before do valid_signin admin end it "should be able to delete another user" do expect { delete user_path(non_admin) }.to change(User, :count).by(-1) end describe "can destroy others" do before do puts admin.admin? delete user_path(non_admin) puts response.success? end #specify{response.should be_success} specify{response.should_not be_redirect} end describe "cannot destroy himself" do before do delete user_path(admin) puts response.success? end #specify{response.should_not be_success} specify{response.should be_redirect} end end . . . end
除了"can destroy others"
测试之外,所有测试都通过。
但是 ,如果我puts response.success?
在每次delete
请求之后,我总是得到False
,所以没有任何请求“成功”。
手动与webapp交互并删除用户工作正常,所以我认为response.success
并不意味着detroy
(或任何请求)不成功,而是其他。 我读到它与HTTP响应200/302/400之间的区别有关 ,但我不完全确定。
为了记录,这是我的User#destroy
:
def destroy User.find(params[:id]).destroy flash[:success]="User destroyed." redirect_to users_path end
对此有何看法? 谢谢!
编辑
这是我的工厂:
FactoryGirl.define do factory :user do sequence(:name){ |n| "Person #{n}" } sequence(:email){ |n| "person_#{n}@example.com"} password "foobar" password_confirmation "foobar" factory :admin do admin true end end end
根据@Peter Alfvin的建议编辑2 ,我换了一行
let(:user){FactoryGirl.create(:user)}
至
let(:admin){FactoryGirl.create(:admin)}
并且所有user
都是admin
。 我还添加了一个puts admin.admin?
在delete
请求之前。 还是行不通!
编辑3
改变测试"can destroy others"
:
describe "can destroy others" do before do puts admin.admin? delete user_path(non_admin) puts response.success? end #specify{response.should be_success} specify{response.should_not be_redirect} end
似乎也没有帮助。
对于您的“管理员”案例,您仍然以“常规”用户而非管理员用户身份创建和登录,这就是为什么您无法销毁其他任何人。
response.success确实引用了HTTP响应代码。 默认情况下,我相信这是200范围内的任何东西。 redirect_to在300范围内。
确保您的用户工厂包含此行
factory :user do #your user factory code factory :admin do admin true end end
然后FactoryGirl.create(:admin)
将返回一个管理员用户,或者您也可以使用user.toggle!(:admin)
将标准用户切换为管理员用户。
试试这个吧
describe "as admin user" do let(:admin){FactoryGirl.create(:admin)} let(:non_admin){FactoryGirl.create(:user)} before do valid_signin admin end it "should be able to delete another user" do expect { delete user_path(non_admin) }.to change(User, :count).by(-1) end it "can destroy others" do # before do puts admin.admin? delete user_path(non_admin) puts response.success? end #specify{response.should be_success} specify{response.should_not be_redirect} end it "cannot destroy himself" do before do delete user_path(admin) puts response.success? end #specify{response.should_not be_success} specify{response.should be_redirect} end end
describe创建了一个魔术类,根据我的理解,它成为了描述类的一个子类。 Rails有很多这种魔力,它可能会让人感到困惑。 另外我还没有看到你的控制器,但是当你摧毁一个用户时你会发生什么呢?因为如果你按照教程那么将会有一个重定向delete
通过浏览器发送会在UsersController
调用你的destroy
方法,在本教程中有这个line redirect_to users_url
so response.should_not be_redirect
将始终失败,因为规范错误而不是控制器。