2015-06-21 77 views
1

我有一个验证模块,包含在我的控制器中。测试被调用两次的RSpec模拟

在我的用于管理员操作的控制器中,他们都继承了AdminController,它们在每个控制器之前调用require_permission :admin以确保当前用户是管理员。

在我的另一个控制器中,我拨打require_permission? :view_admins来验证用户是否有权查看其他管理员的详细信息。当我运行该规范来测试require_permission :view_admins被调用时,我得到一个错误,说require_permission被调用了:admin

如果我改变我的规范,并添加一个测试,require_permission?被调用:admin在我的测试中它被调用:view_admins然后规范通过。有没有办法只用:view_admins来测试它呢?

这里是通过规范:

it 'requires view_admins permission' do 
     expect(controller).to receive(:require_permission).with :admin 
     expect(controller).to receive(:require_permission).with :view_admins 
     get :admins 
end 

和发生故障的规格:

it 'requires view_admins permission' do 
     expect(controller).to receive(:require_permission).with :view_admins 
     get :admins 
end 

回答

1

的最佳方式,国际海事组织,将包装你的所有管理身份验证的测试中一个期望:admin调用的上下文。

describe MyController do 
    context "when authenticated" do 
    before do 
     expect(controller).to receive(:require_permission).with :admin 
    end 

    it 'requires view_admins permission' do 
     expect(controller).to receive(:require_permission).with :view_admins 
     get :admins 
    end 
    end 
end 

如果你不想这样做,那么你可以使用allow吃的方法的所有意外调用:

it 'requires view_admins permission' do 
    allow(controller).to receive(:require_permission) 
    expect(controller).to receive(:require_permission).with :view_admins 
    get :admins 
end 

话虽这么说,因为这些控制器的测试,考虑写他们作为验收测试(哪种测试行为)而不是单元测试(经常测试实施)。例如:

describe AdminController do 
    context "when logged in as an admin" do 
    let(:permissions) { [:admin] } 
    before { login_with *permissions } 

    describe "#admin" do 
     subject { get :admin } 

     context "with view_pages" do 
     let(:permissions) { [:view_pages] } 
     it { is_expected.to respond_with 200 } 
     end 

     context "without view_pages" do 
     it { is_expected.to respond_with 403 } 
     end 
    end 
    end 
end