如何使用RSpec正确测试CanCan功能 [英] How do I properly test CanCan abilities with RSpec

查看:85
本文介绍了如何使用RSpec正确测试CanCan功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是第一次测试CanCan的功能,但很沮丧。我缺少了一些东西……即使我在can:invite_to块中返回false / true,我仍然没有通过规格。我是否缺少使用CanCan匹配器?还是存根?或在CanCan中定义功能?



我想念什么吗?



ability.rb

 类能力
包括CanCan ::能力

def initialize(user)
user || = User.new

can:invite_to,Network do | network |
network.allows_invitations? && (user.admin?|| user.can_send_invitations_for?(网络))
结束
结束
结束

ability_spec.rb

 需要 cancan 
需要'cancan / matchers'
require_relative'../../app/models/ability.rb'

类网络;结束;

描述能力做
let(:ability){Ability.new(@user)}

描述 #invite_to,网络做
上下文启用网络级邀请时
let(:network){stub(allows_invitations ?: true)}

它允许管理员执行
@user = stub (admin ?: true)
能力。应该be_able_to(:invite_to,网络)
结束

它允许成员(如果启用了成员的邀请特权)执行
@user = stub(admin ?: false,can_send_invitations_for ?: true)
能力。应该be_able_to(:invite_to,网络)
结束

它如果成员的邀请特权已禁用 do
@user = stub(admin ?: false,can_send_invitations_for ?: false)
能力。should_notbe_able_to(:invite_to,网络)
结束
结束
结束
结束

故障

  1)Ability#invite_to,启用网络级邀请时的网络允许管理员
失败/错误:capability.should be_able_to(:invite_to,network)
能够:invite_to#< RSpec :: Mocks :: Mock:0x3fe3ed90444c @ name = nil>
#./spec/models/ability_spec.rb:16:in在< top(必需)>'中的块(4个级别)中

2)Ability#invite_to,网络何时如果启用了会员的邀请特权,则启用网络级邀请会允许该会员
失败/错误:capability.should be_able_to(:invite_to,network)
应该能够:invite_to#< RSpec ::嘲笑::嘲笑:0x3fe3edc27408 @ name = nil>
#./spec/models/ability_spec.rb:21:在< top(必需)>'

解决方案

  let(:network)做
n = Network.new
n.stub!(:allows_invitations?=> true)
n
结束

如果您在编写代码时运行代码,则Can块内的代码将永远无法到达。您对存根的调用返回RSpec :: Mocks :: Mock类的对象;它必须属于Network类,CanCan才能应用规则。


I am testing CanCan abilities for the first time and am stumped. I'm missing something...even if I return false/true inside of the can :invite_to block I am still not getting passing specs. Am I missing using the CanCan matchers? or stubs? or definiing abilities in CanCan?

Anything I'm missing?

ability.rb

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new

    can :invite_to, Network do |network|
      network.allows_invitations? && (user.admin? || user.can_send_invitations_for?(network))
    end
  end
end

ability_spec.rb

require 'cancan'
require 'cancan/matchers'
require_relative '../../app/models/ability.rb'

class Network; end;

describe Ability do
  let(:ability) { Ability.new(@user) }

  describe "#invite_to, Network" do
    context "when network level invitations are enabled" do
      let(:network) { stub(allows_invitations?: true) }

      it "allows an admin" do
        @user = stub(admin?: true)
        ability.should be_able_to(:invite_to, network)
      end

      it "allows a member if the member's invitation privileges are enabled" do
        @user = stub(admin?: false, can_send_invitations_for?: true)
        ability.should be_able_to(:invite_to, network)
      end

      it "denies a member if the member's invitation privileges are disabled" do
        @user = stub(admin?: false, can_send_invitations_for?: false)
        ability.should_not be_able_to(:invite_to, network)
      end
    end
  end
end

Failures

  1) Ability#invite_to, Network when network level invitations are enabled allows an admin
     Failure/Error: ability.should be_able_to(:invite_to, network)
       expected to be able to :invite_to #<RSpec::Mocks::Mock:0x3fe3ed90444c @name=nil>
     # ./spec/models/ability_spec.rb:16:in `block (4 levels) in <top (required)>'

  2) Ability#invite_to, Network when network level invitations are enabled allows a member if the member's invitation privileges are enabled
     Failure/Error: ability.should be_able_to(:invite_to, network)
       expected to be able to :invite_to #<RSpec::Mocks::Mock:0x3fe3edc27408 @name=nil>
     # ./spec/models/ability_spec.rb:21:in `block (4 levels) in <top (required)>'

解决方案

  let(:network) do 
    n = Network.new
    n.stub!(:allows_invitations? => true)
    n
  end

If you run the code as you wrote it, the code inside the Can block is never reached. Your call to stub returns an object of class RSpec::Mocks::Mock; it must be of class Network for CanCan to apply the rule.

这篇关于如何使用RSpec正确测试CanCan功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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