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将始终失败,因为规范错误而不是控制器。

Interesting Posts