Reputation: 13002
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.
Upvotes: 23
Views: 10317
Reputation: 9927
The most straightforward approach that comes into my mind is to mock the controller before doing the request:
session = { app_id: @app.id }
allow_any_instance_of(SomeController).to receive(:session).and_return(session)
get some_resources_path
expect(response).to ...
Upvotes: -1
Reputation: 352
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
Upvotes: 15