在before块内部调用时,Rspec存根不起作用

时间:2017-07-09 05:10:36

标签: ruby-on-rails ruby rspec

我有一个rspec存根问题。我正在关注此文档https://relishapp.com/rspec/rspec-mocks/docs/working-with-legacy-code/any-instance

describe Api::V1::ActionsController, type: :controller do
  let(:admin) { create :admin }

  subject { response }

  describe 'GET #index' do
    before :each do
      get :index
    end

    context 'admin' do
      before :each do
        allow_any_instance_of(ApplicationController).to receive(:current_user).and_return admin
        allow_any_instance_of(ApplicationController).to receive(:authenticate!).and_return true
      end

      it 'expects 200' do
        expect(response.status).to eq 200
      end
    end
  end

此测试失败。有趣的是,如果我把这些存根放到spec_helper.rb喜欢

  config.before :each do
    allow_any_instance_of(ApplicationController).to receive(:current_user).and_return admin
    allow_any_instance_of(ApplicationController).to receive(:authenticate!).and_return true
  end

它工作正常。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

猜测问题在于这段代码:

before :each do
  get :index
end

在存根之前运行

before :each do
  allow_any_instance_of(ApplicationController).to receive(:current_user).and_return admin
  allow_any_instance_of(ApplicationController).to receive(:authenticate!).and_return true
end

before块从外向内运行,带有存根的块嵌套得更深。因此,当您存根方法时,get :index已经执行。

请改为尝试:

describe 'GET #index' do
  subject do   # define what `subject` will do, but don't actually run it just yet
    get :index
  end

  context 'admin' do
    before :each do
      allow_any_instance_of(ApplicationController).to receive(:current_user).and_return admin
      allow_any_instance_of(ApplicationController).to receive(:authenticate!).and_return true
    end

    it 'returns 200' do
      expect(subject).to be_success
      #      ^^^ now it's only here that the controller action is executed
    end
  end
end