RSpec 3 Error undefined method `get' in request test - ruby-on-rails

After migration on RSpec 3 request test fails.
Here is my test
describe 'GET /api/v1/activities' do
let!(:user) { create(:user) }
subject { json['activities'] }
context 'when not authenticated' do
let(:token) { user.authentication_token }
let(:email) { 'unregistered.user#mail.com' }
before :each do
get '/api/v1/activities', {}, {token: token, email: email}
end
it { expect(response).to_not be_success }
end
end
Here is rspec log
Activities GET /api/v1/activities when not authenticated
Failure/Error: get '/api/v1/activities', {}, {token: token, email: email}
NoMethodError:
undefined method `get' for #<RSpec::ExampleGroups::Activities::GETApiV1Activities::WhenNotAuthenticated:0x0000000becfaf8>
What can it be?

Ok, migration to RSpec3 was the cause of this issue.
I'd resolved it by migrating to RSpec 2.99.0 and I received a hint to add this code to my spec_helper
RSpec.configure do |config|
config.infer_spec_type_from_file_location!
end
Now it works. Hurray!

I already had infer_spec_type_from_file_location! set, but we still used the capybara feature syntax here, which probably sets the type to feature. Once I changed feature to describe, it worked.

Try to add helper to request specs. In spec_helper.rb:
config.include RSpec::Rails::RequestExampleGroup, type: :request
Also i assume that you have type: :request in you spec definition.

Related

Devise Rspec undefined method `env' for nil:NilClass

I've scoured SO and no one else's results seem to work for me:
I have a ControllerHelper method for my Spec based off what was suggested for Devise:
def login_existing_user
#request.env["devise.mapping"] = Devise.mappings[:user]
user = FactoryGirl.create(:user)
company = FactoryGirl.create(:company)
user.company_id = company.id
sign_in user
end
I am also creating a Company in this method since that's step 2 of the sign up process for a user to be able to get my authenticated homepage.
At this point, I'm just trying to log the user in with my ScansControllerSpec:
RSpec.describe ScansController, type: :controller do
before(:all) do
login_existing_user
#device = build(:device)
end
describe "GET #create" do
it "returns http success" do
get :create, :device_id => #device.id
puts response
# expect(response).to have_http_status(:success)
end
end
....
end
But I'm getting this for every one of my CRUD method RSpecs:
1) ScansController GET #create returns http success
Failure/Error: #request.env["devise.mapping"] = Devise.mappings[:user]
NoMethodError:
undefined method `env' for nil:NilClass
# ./spec/support/controller_helpers.rb:15:in `login_existing_user'
# ./spec/controllers/scans_controller_spec.rb:6:in `block (2 levels) in <top (required)>'
As other posts have suggested, I am including the Devise::TestHelpers in my rails_helper.rb file. I've also included my ControllerHelpers:
RSpec.configure do |config|
config.include Devise::TestHelpers, type: :controller
config.include Warden::Test::Helpers
Warden.test_mode!
config.infer_spec_type_from_file_location!
config.include ControllerHelpers, type: :controller
config.after do
Warden.test_reset!
end
end
In the end, I need to be able to log a user in to test that protected controller methods work. I'm not sure if this is an association problem, so I'll add that a user has to have a company, and a company has to have a subscription in order to successfully log in.
... but I can't even get that far since this error is holding me back.
Seemed to have gotten past this issue by following: http://willschenk.com/setting-up-testing/

Getting undefined method `get' for #<RSpec::ExampleGroups in my rspec

Rails 4.2.5, rspec-rails 3.0.2
I want to test my API. So I created requests directory inside /spec. There is a file called projects_spec.rb
Here is the code:
describe 'Projects API' do
describe 'GET /projects' do
it 'should return 401 HTTP code' do
get '/api/v1/projects'
expect(response.status).to eq(401)
end
end
end
And when I run this test I'm getting
NoMethodError: undefined method `get' for #RSpec::ExampleGroups::ProjectsAPI::GETProjects:0x007fee73ad9b48>
What's wrong?
# rails_helper.rb
config.infer_spec_type_from_file_location!
describe 'Projects API', type: :request do
# ...
end
Also, make sure you've included require 'rails_helper' in your projects_spec.rb.

Why is RSpec not passing my headers to Rails?

I am trying to test my Rails application using RSpec, but my tests are failing because RSpec seems to not be passing the headers I give it to Rails.
I have a UsersController that includes ApplicationHelper, and in ApplicationHelper I have a method that accesses the headers hash. Indexing it by my SESSION_KEY header returns nil. If I puts headers inside that method, the hash does not contain the header I have supplied, only the following: {"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff"}.
Here is the relevant part of my RSpec spec:
require 'rails_helper'
describe Api::V1::UsersController, type: :request do
let(:user) { User.create(name: 'TestUser', email: 'someone#example.com', password: 'password123', password_confirmation: 'password123') }
let(:id) { user.id }
let(:sess) { user.sessions.create }
before { get "/api/v1/users/#{id}" }
# Snipped other tests
context 'with authentication' do
context 'with a valid id' do
it 'returns full user information' do
get "/api/v1/users/#{id}", nil, {'HTTP_SESSION_KEY': sess.key}
response_user = response_json[:user]
expect(response.status).to eq 200
expect(response_user).to_not be_nil
expect(response_user[:name]).to eq user[:name]
expect(response_user[:email]).to eq user[:email]
end
end
end
def response_json
JSON.parse(response.body, symbolize_names: true)
end
end
I have also tried passing the SESSION_KEY header without HTTP_ before it, and that did not work. I have also tried moving it up to the top get in the before block to see if it was a context issue, and that did not work either.
Docs say the above should work, but if for some reason rspec is interpreting your test as a :controller test and not a :request test then you need to do this (just before your get call):
request.env["HTTP_SESSION_KEY"] = sess.key

How to implement RSpec session controller test with invalid user credentials

I'm writing RSpec tests for my SessionsController. My tests work fine when testing session#create with valid credentials. However, I want to also write tests for what happens when the users credentials are invalid, such as redirecting back to the sign in page, setting a flash alert, etc. But for any of these tests, I'm getting an error:
1) SessionsController POST #create when password is INCORRECT
Failure/Error: post :create, user: {username: 'Example', password: ''}
ArgumentError:
uncaught throw :warden
# ./spec/support/default_params.rb:7:in `process_with_default_params'
# ./spec/controllers/sessions_controller_spec.rb:24:in `block (4 levels) in <top (required)>'
Here's my sessions_controller_spec.rb code:
require 'spec_helper'
describe SessionsController do
before do
#request.env["devise.mapping"] = Devise.mappings[:user]
end
describe 'POST #create' do
context "when password is INCORRECT" do
let!(:user) { FactoryGirl.create(:user, username: 'Example', password: 'Secr3t&$') }
before(:each) do
post :create, user: { username: 'Example', password: '' }
end
it { should set_the_flash[:alert].to('Invalid username or password.') }
it { should respond_with(:redirect) }
it { should redirect_to(:new_user_session) }
end
end
Here's my spec_helper.rb code:
RSpec.configure do |config|
config.include Devise::TestHelpers, type: :controller
end
Any help would be much appreciated. Thanks!
I know it is too late now but in case this helps someone else: you need to add setup_controller_for_warden to your before block, so it becomes:
before do
#request.env["devise.mapping"] = Devise.mappings[:user]
setup_controller_for_warden
end
Also it would be better to use the translation for you assertion. In rspec 3 format, the assertion should like this:
expect(flash[:alert]).to eq(I18n.t('devise.failure.invalid'))

Devise and Rspec - undefined method `authenticate!' for nil:NilClass

I'm trying to test my controller for access from unregistered users. Im using devise (3.3.0) and rspec (3.0.0).
spec/controllers/dares_controller_spec.rb
require 'rails_helper'
describe DaresController do
let(:challenger) { create(:user) }
let(:acceptor) { create(:user) }
let(:challenge) { create(:challenge) }
let(:dare) { create(:dare) }
let(:user) { create(:user) }
describe 'Guest access to dares' do
describe 'GET #show' do
it "redirects to root" do
get :show, id: dare.id, challenge_id: challenge.id
expect(response).to require_login
end
end
end
end
In the controller:
dares_controller.rb
before_action :authenticate_user!
def show
end
I get the following error:
Failures:
1) DaresController Guest access to dares GET #show redirects to root
Failure/Error: get :show, id: dare.id, challenge_id: challenge.id
NoMethodError:
undefined method `authenticate!' for nil:NilClass
# ./spec/controllers/dares_controller_spec.rb:16:in `block (4 levels) in <top (required)>'
I tried adding
RSpec.configure do |config|
config.include Devise::TestHelpers, :type => :controller
end
to my spec_helper / rails_helper but it didnt fix the problem. I googled for solutions for a few hours, bothing seems to help.
Matcher - require_login
RSpec::Matchers.define :require_login do |expected|
match do |actual|
expect(actual).to redirect_to Rails.application.routes.url_helpers.new_user_session_path
end
failure_message do |actual|
"expected to require login to access the method"
end
failure_message_when_negated do |actual|
"expected not to require login to access the method"
end
description do
"redirect to the login form"
end
end
change this line:
describe DaresController do
to this one:
RSpec.describe DaresController, type: :controller do
Since you configure the spec_helper or rails_helper with:
config.include Devise::TestHelpers, type: :controller
You should set the correct spec type to works properly. It's a rspec behavior in rspec~3

Resources