在Rspec请求规范中设置会话变量

时间:2018-11-23 13:43:24

标签: ruby-on-rails session rspec

我正在尝试在请求规范中设置会话变量。

我已经尝试了以下方法来做到这一点:

RSpec.describe 'Application Controller' do
  context 'updating an application' do
    before :each do
      @app = create(:application, step: 'investigation')
    end

    it 'should update app status' do
      Status.create(app_id: @app.id, name: Status.names[:start])
      request.session[:app_id] = @app.id
      patch "/applications/start",
            params: s_params
      expect(response).to redirect_to(offers_path)
    end
  end
end

我尝试将request替换为@request都导致相同的输出。

NoMethodError:
  undefined method `session' for nil:NilClass

然后我尝试将其设置为:

session[:app_id] = @app.id

这将产生:

NoMethodError:
  undefined method `session' for nil:NilClass

,并按如下设置:

patch "/applications/start",
      params: s_params,
      session: {"app_id" => @app.id}

这将产生:

 ArgumentError:
   unknown keyword: session

我的版本:

╰>>> ruby -v
ruby 2.4.5p335 (2018-10-18 revision 65137) [x86_64-darwin18]

╰>>> rails -v
Rails 5.2.1

╰>>> rspec -v
RSpec 3.8
  - rspec-core 3.8.0
  - rspec-expectations 3.8.1
  - rspec-mocks 3.8.0
  - rspec-rails 3.8.0
  - rspec-support 3.8.0

documentation的角度来看,这表明我们可以利用这些会话,但没有给出明确的示例来说明如何实现。

2 个答案:

答案 0 :(得分:1)

首先,要点评论...

我建议对RSpec测试定义使用“类型:”。无论如何,这都是件好事:易于通过审查确定,我们将能够为该类型的测试定义一些扩展名/自定义项(如果需要)。

第二点

在请求之前,我们没有request / response / controller方法(实例)。只有在要求之后,我们才会有它们。因此,在您的示例中,我们不能在request.session[:app_id] = @app.id之前使用patch ...

第三点

@app是变量的危险名称,不确定是否会出现问题,但最好将其重命名

一种可能的解决方案

您可以尝试使用一些存根,例如: allow_any_instance_of(ActionDispatch::Request).to receive(:session) { { app_id: '11' } }

注释

请求方法get / post / patch /等与类似的控制器测试方法不同。它们都是通过process方法处理的。您可以找到更多详细信息here

答案 1 :(得分:0)

您可以执行以下操作:

- RSpec.describe 'Application Controller' do
+ RSpec.describe 'Application Controller', type: :request do

然后:

session[:app_id] = @app.id