Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set a session var in Rspec Request spec

I am trying to set a session variable in a request spec.

I have tried the following things to do this:

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

I have tried substituting request with @request both result in the same output.

NoMethodError:
  undefined method `session' for nil:NilClass

then I have tried just setting as:

session[:app_id] = @app.id

which will yield:

NoMethodError:
  undefined method `session' for nil:NilClass

and also setting it like this:

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

which will yield:

 ArgumentError:
   unknown keyword: session

My versions:

╰>>> 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

Looking at the documentation it suggests we could leverage the sessions but does not give a clear example of how we would do this.

like image 729
TheLegend Avatar asked Nov 23 '18 13:11

TheLegend


1 Answers

First of all, little remark...

I recommend using 'type:' for RSpec test definition. It's good in anyways: easy to determinate by review and we will have the ability to define some extensions/customization for that type of tests(if needed).

The second point

We don't have request / response / controller methods(instance) before the request. Only after request, we will have them. By this reason we can't use request.session[:app_id] = @app.id before patch in your example...

The third point

@app it is a risky name of variable, not sure it will be a problem or not, but will be better to rename it

One of the possible solution

You can try to use some stubs for it, for example: allow_any_instance_of(ActionDispatch::Request).to receive(:session) { { app_id: '11' } }

Notes

The requests methods get / post / patch / and etc are differrent from similar controller test methods. All they are handling by process method. More details you can find here

like image 89
s.stv Avatar answered Sep 22 '22 17:09

s.stv