如果没有删除链接,则进行销毁的 Rspec 测试 [英] Rspec test for destroy if no delete link

查看:39
本文介绍了如果没有删除链接,则进行销毁的 Rspec 测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 railstutorial.org 上最新的 Rails 教程,但我被困在某个练习中(http://ruby.railstutorial.org/chapters/updating-showing-and-deleting-users#sec:updating_deleting_exercises).您必须编写 rspec/capybara 测试以确保管理员无法删除自己.我有实施工作,但无法让测试正常工作.这是我的代码.我在这里发现了类似的问题:Ruby on Rails 语法https://getsatisfaction.com/railstutorial/topics/how_to_prevent_admin_user_from_deleting_themselves.但我认为这是一个较旧的教程,而不是同一个问题.

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). You have to write a rspec/capybara test to make sure the admin can't delete themself. 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 . But I think it is an older tutorial and not the same question.

这是spec/requests/user_pages_spec.rb中的相关代码:

Here is the relevant code in 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.

The error message says that the user count is getting reduced by 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)

使用 Ruby v1.9.3,Rails v3.2.3.默认情况下,管理员没有删除链接.

Using Ruby v1.9.3, Rails v3.2.3. By default, there is no delete link for admins.

Edit2:这是我的工作:

Here is what I got working:

spec/controllers/users_controller_spec.rb

spec/controllers/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

推荐答案

您的 before_filter 的语法不正确.调用应如下所示

The syntax of your before_filter is incorrect. 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. 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

至于您的测试,它失败了,因为您在控制器中调用了 delete 方法而不是 destroy 操作.来自 ActiveRecord::Relation

As for your test, it's failing because you are calling the delete method instead of the destroy action in your controller. From ActiveRecord::Relation

Active Record 对象没有被实例化,所以对象的回调不执行,包括任何 :dependent 关联选项或观察者方法.

Active Record objects are not instantiated, so the object’s callbacks are not executed, including any :dependent association options or Observer methods.

由于他们要求您使用 rspec/capybara,您可以使用 click_link 方法来触发销毁操作.由于您在一个包含多个列表的索引页面上,您应该查看 Capybara::Node::Finders 以便可靠地选择正确的按钮.

Since they're asking you to use rspec/capybara, you can use the click_link method to trigger the destroy action. 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.

由于您要测试控制器,而不是视图,您可以使用:

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

这篇关于如果没有删除链接,则进行销毁的 Rspec 测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆