简体   繁体   English

如果没有删除链接,则Rspec测试为destroy

[英]Rspec test for destroy if no delete link

I'm going through the latest rails tutorial on railstutorial.org and I am stuck on a certain exercise (#8 on http://ruby.railstutorial.org/chapters/updating-showing-and-deleting-users#sec:updating_deleting_exercises ). 我正在浏览railstutorial.org上的最新rails指南,我仍然坚持参加某项练习( http://ruby.railstutorial.org/chapters/updating-showing-and-deleting-users#sec:updating_deleting_exercises上的#8 )。 You have to write a rspec/capybara test to make sure the admin can't delete themself. 你必须写一个rspec / capybara测试,以确保管理员不能删除自己。 I have the implementation working, but can't get the test to work right. 我有实施工作,但无法让测试工作正常。 Here is my code. 这是我的代码。 I found similar questions here: Ruby on Rails syntax and https://getsatisfaction.com/railstutorial/topics/how_to_prevent_admin_user_from_deleting_themselves . 我在这里发现了类似的问题: Ruby on Rails语法https://getsatisfaction.com/railstutorial/topics/how_to_prevent_admin_user_from_deleting_theself But I think it is an older tutorial and not the same question. 但我认为这是一个较旧的教程而不是同一个问题。

Here is the relevant code in spec/requests/user_pages_spec.rb: 以下是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

The error message says that the user count is getting reduced by 1. 错误消息表示用户数减少了1。

For completeness, here is my (working) implementation: 为了完整性,这是我的(工作)实现:

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

Where am I going wrong, thanks? 我哪里错了,谢谢? (I left out some methods, but hopefully there is enough to figure out what I'm trying to do) (我遗漏了一些方法,但希望有足够的方法来弄清楚我正在尝试做什么)

Edit: Using Ruby v1.9.3, Rails v3.2.3. 编辑:使用Ruby v1.9.3,Rails v3.2.3。 By default, there is no delete link for admins. 默认情况下,管理员没有删除链接。

Edit2: Here is what I got working: Edit2:这就是我的工作:

spec/controllers/users_controller_spec.rb 规格/控制器/ 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 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

The syntax of your before_filter is incorrect. before_filter的语法不正确。 The call should look like this 电话应该是这样的

before_filter :current_admin, :only => [:destroy]

You would also probably be better off keeping this logic in the destroy action. 你也可能最好将这个逻辑保留在destroy动作中。 Since it only applies to that action, I don't see any reason to move it into a separate method/filter. 由于它仅适用于该操作,因此我认为没有任何理由将其移动到单独的方法/过滤器中。 The other questions you pointed to are in fact from older versions of the tutorial, but the logic is nonetheless the same: 您指出的其他问题实际上来自本教程的旧版本,但逻辑仍然相同:

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

As for your test, it's failing because you are calling the delete method instead of the destroy action in your controller. 至于你的测试,它失败了,因为你正在调用delete方法而不是你控制器中的destroy动作。 From ActiveRecord::Relation 来自ActiveRecord :: Relation

Active Record objects are not instantiated, so the object's callbacks are not executed, including any :dependent association options or Observer methods. Active Record对象未实例化,因此不执行对象的回调,包括任何:依赖关联选项或Observer方法。

Since they're asking you to use rspec/capybara, you can use the click_link method to trigger the destroy action. 由于他们要求您使用rspec / capybara,因此您可以使用click_link方法触发destroy操作。 Since you're on an index page with multiple listings, you should look into Capybara::Node::Finders in order to select the correct button reliably. 由于您在具有多个列表的索引页面上,因此您应该查看Capybara :: Node :: Finders以便可靠地选择正确的按钮。

Edit: Since you're looking to test the controller, not the view, you can test with: 编辑:由于您要测试控制器而不是视图,您可以测试:

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

This can be tested in the user_pages_spec which is pretty much what the railstutorial.org book seems to want you to do. 这可以在user_pages_spec中进行测试,这与railstutorial.org书籍似乎要求你做的几乎相同。 (Ruby on Rails Tutorial Chapter 9, Exercise 9). (Ruby on Rails教程第9章,练习9)。 Whether that is a good idea I leave up to greater minds. 这是否是一个好主意我会留下更多的思想。

The test code in user_pages_spec.rb would look like this: 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

the delete user_path(admin.id) will mimic clicking 'delete' and works in rspec-capybara. 删除user_path(admin.id)将模仿单击“删除”并在rspec-capybara中工作。 This will pass with your controller code above, assuming you change your error message to match mine or vice-versa. 这将通过上面的控制器代码传递,假设您更改错误消息以匹配我的错误消息,反之亦然。

Also, the before_filter syntax in the UsersController seems to work either with or without the [] if there is only item. 此外,如果只有item,那么UsersController中的before_filter语法似乎可以使用或不使用[]。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM