ruby-on-rails 在Rspec请求规范中设置会话变量

pnwntuvh  于 2022-12-05  发布在  Ruby
关注(0)|答案(2)|浏览(151)

我正在尝试在请求规范中设置会话变量。
我已经尝试了以下方法来做到这一点:

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,它表明我们可以利用会话,但没有给予如何做到这一点的清晰示例。

idv4meu8

idv4meu81#

"首先,小小的评论“
我推荐使用'type:'作为RSpec测试定义。它在以下方面都很好:易于通过审查确定,我们将能够为该类型的测试定义一些扩展/自定义(如果需要)。
"第二点"
在请求之前我们没有request/response/controller方法(示例)。只有在请求之后,我们才会有它们。因此,在你的例子中,我们不能在patch之前使用request.session[:app_id] = @app.id...
"第三点"
@app这是一个有风险的变量名,不确定它是否会有问题,但最好重命名它

可能的解决方案之一

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

备注

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

qhhrdooz

qhhrdooz2#

我想到的最直接的方法是在执行请求之前对控制器进行模拟:

session = { app_id: @app.id }
 allow_any_instance_of(SomeController).to receive(:session).and_return(session)

 get some_resources_path
 expect(response).to ...

相关问题