[英]Rspec test for destroy if no delete link
我正在浏览railstutorial.org上的最新rails指南,我仍然坚持参加某项练习( http://ruby.railstutorial.org/chapters/updating-showing-and-deleting-users#sec:updating_deleting_exercises上的#8 )。 你必须写一个rspec / capybara测试,以确保管理员不能删除自己。 我有实施工作,但无法让测试工作正常。 这是我的代码。 我在这里发现了类似的问题: Ruby on Rails语法和https://getsatisfaction.com/railstutorial/topics/how_to_prevent_admin_user_from_deleting_theself 。 但我认为这是一个较旧的教程而不是同一个问题。
以下是spec / requests / user_pages_spec.rb中的相关代码:
describe "User pages" do
subject { page }
describe "delete links" do
describe "as an admin user" do
let(:admin) { FactoryGirl.create(:admin) }
before do
sign_in admin
visit users_path
end
it "should not be able to delete themself" do
expect { admin.delete }.should_not change(User, :count)
end
end
end
end
end
错误消息表示用户数减少了1。
为了完整性,这是我的(工作)实现:
class UsersController < ApplicationController
before_filter :current_admin, only: :destroy
def current_admin
@user = User.find(params[:id])
redirect_to users_path, notice: "Cannot delete current admin" if current_user?(@user)
end
end
我哪里错了,谢谢? (我遗漏了一些方法,但希望有足够的方法来弄清楚我正在尝试做什么)
编辑:使用Ruby v1.9.3,Rails v3.2.3。 默认情况下,管理员没有删除链接。
Edit2:这就是我的工作:
规格/控制器/ users_controller_spec.rb
require 'spec_helper'
describe UsersController do
describe "admins" do
let(:admin) { FactoryGirl.create(:admin) }
it "should not be able to delete themself" do
sign_in admin
expect { delete :destroy, :id => admin.id }.should_not change(User, :count)
end
end
end
users_controller.rb
def destroy
@user = User.find(params[:id])
if current_user?(@user)
flash[:error] = "Cannot delete current admin"
else
@user.destroy
flash[:success] = "User destroyed."
end
redirect_to users_path
end
before_filter的语法不正确。 电话应该是这样的
before_filter :current_admin, :only => [:destroy]
你也可能最好将这个逻辑保留在destroy动作中。 由于它仅适用于该操作,因此我认为没有任何理由将其移动到单独的方法/过滤器中。 您指出的其他问题实际上来自本教程的旧版本,但逻辑仍然相同:
class UsersController < ApplicationController
def destroy
@user = User.find(params[:id])
if current_user?(@user)
flash[:error] = "Cannot delete current admin"
else
user.destroy
flash[:notice] = "User was successfully deleted"
end
redirect_to users_path
end
end
至于你的测试,它失败了,因为你正在调用delete方法而不是你控制器中的destroy动作。 来自ActiveRecord :: Relation
Active Record对象未实例化,因此不执行对象的回调,包括任何:依赖关联选项或Observer方法。
由于他们要求您使用rspec / capybara,因此您可以使用click_link方法触发destroy操作。 由于您在具有多个列表的索引页面上,因此您应该查看Capybara :: Node :: Finders以便可靠地选择正确的按钮。
编辑:由于您要测试控制器而不是视图,您可以测试:
describe "admins" do
let(:admin) { FactoryGirl.create(:admin) }
it "should not be able to delete themself" do
sign_in admin
expect { delete :destroy, :id => admin.id }.should_not change(User, :count)
end
end
这可以在user_pages_spec中进行测试,这与railstutorial.org书籍似乎要求你做的几乎相同。 (Ruby on Rails教程第9章,练习9)。 这是否是一个好主意我会留下更多的思想。
user_pages_spec.rb中的测试代码如下所示:
describe "I should not be able to delete admins" do
before { delete user_path(admin.id) }
it { should_not have_selector('div.alert.alert-error', text: 'Admins cannot delete themselves') }
end
删除user_path(admin.id)将模仿单击“删除”并在rspec-capybara中工作。 这将通过上面的控制器代码传递,假设您更改错误消息以匹配我的错误消息,反之亦然。
此外,如果只有item,那么UsersController中的before_filter语法似乎可以使用或不使用[]。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.