我的Ability.rb中定义了以下能力:
if user.role? :chief
can [:action1, :action2], Request, user: {id: user.subordinate_ids}
end
在我的能力测试中,我有以下内容:
subject{ Ability.new(user) }
let(:user) { create(:chief_user) }
let(:subordinate) { create(:user, boss: user) }
it { is_expected.to be_able_to([:action1, :action2], Request.new(user: subordinate)) }
该功能在进行手动测试时按预期工作,但我无法使此测试工作。我已尝试使用适当的参数Request.create,但我仍然得到相同的结果。
我做了一些调试并且相应的关联是有序的(主管有下属,请求属于下属,所以实际的测试是主管只能动作1,动作2他的下属的请求)。
我使用CanCanCan和RSpec进行测试。
有关如何进行此测试的任何见解?
答案 0 :(得分:0)
rspec的let语法基本上是使用Proc(延迟加载),所以在你调用它之前它实际上并没有被持久化。当你在一个规范中调用它时,你有时会测试一些尚未持久化的东西。
您可以通过添加前块
来检查subject{ Ability.new(user) }
let(:user) { create(:chief_user) }
let(:subordinate) { create(:user, boss: user) }
it { is_expected.to be_able_to([:action1, :action2], Request.new(user: subordinate)) }
尝试添加下面的前一行
subject{ Ability.new(user) }
let(:user) { create(:chief_user) }
let(:subordinate) { create(:user, boss: user) }
# new line to ensure object exists before test run
before {expect(subordinate).to eq subordinate}
it { is_expected.to be_able_to([:action1, :action2], Request.new(user: subordinate)) }
有点令人沮丧的IMO,但我在此之前遇到了这个问题
答案 1 :(得分:0)
解决这个问题:
subject{ Ability.new(user) }
let!(:user) { create(:chief_user) }
let!(:subordinate) { create(:user, boss: user) }
[:action1, :action2].each do |action|
it { is_expected.to be_able_to(action, Request.new(user: subordinate)}
end
一起做这件事并不奏效。