Test ActionController::RoutingError: uninitialized constant V1::LocationsController - ruby-on-rails

Continued from uninitialized constant error when running tests on Ruby on rails 5 ...
I'm writing test cases for my api controller with namespace - v1 but it seems ROR doesn't understand the namespace V1 exists.
When I run "rails routes", this is what I get:
v1_locations GET /v1/locations(.:format) v1/locations#index
POST /v1/locations(.:format) v1/locations#create
v1_location GET /v1/locations/:id(.:format) v1/locations#show
PATCH /v1/locations/:id(.:format) v1/locations#update
PUT /v1/locations/:id(.:format) v1/locations#update
DELETE /v1/locations/:id(.:format) v1/locations#destroy
and this is what I have in my test file...
class V1::LocationControllerTest < ActionDispatch::IntegrationTest
def setup()
# A bunch of stuff here
end
test "cannot retrieve a list of locations without a valid token" do
get v1_locations_url
assert_response :unauthorized
end
# More tests here...
end
and this is what my controller looks like
class V1::LocationController < ApplicationController
# To be filled once tests run and fail
end
and this is the error message I'm getting...
Error:
V1::LocationControllerTest#test_cannot_create_a_location_without_a_valid_token:
ActionController::RoutingError: uninitialized constant V1::LocationsController
test/controllers/v1/location_controller_test.rb:32:in `block in <class:LocationControllerTest>'
bin/rails test test/controllers/v1/location_controller_test.rb:31
It's also funny that I get page not found error when I send a GET request to /v1/locations
Mmm... What am I missing here?
Thanks,

Check your error log it says ActionController::RoutingError: uninitialized constant V1::LocationsController, while you controller name is LocationController.
Please rename it to LocationsController and rename a file to locations_controller.rb.
You can get more insights about that here

Related

Rails integration test don't see routes

I am writing because I recently added a two-step authorization to active_admin in my application using the gem: 'devise-two-factor'. Everything is working, unfortunately when I started to write tests I noticed that the paths I added do not exist in the test environment (there is an error). What is the reason for this and how to fix it. thanks in advance for your help.
Error:
test_can_setup_2FA_for_admin_user ERROR (325.99s)
Minitest::UnexpectedError: ActionController::RoutingError: No route matches [GET] "/admin/admin_users/6/edit_two_factor"
test/controllers/admin/sessions_controller_test.rb:11:in `block in <class:AdminUsersControllerTest>'
Finished in 325.99535s
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
[SlowTest] AdminUsersControllerTest#test_can_setup_2FA_for_admin_user : 325.99s
routes:
rails routes | grep edit_two_factor
edit_two_factor_authentication_confirmation GET /two_factor_authentication/confirmation/edit(.:format) two_factor_authentication/confirmations#edit {:host=>"571e-77-222-242-230.eu.ngrok.io"}
edit_two_factor_authentication_recovery_code GET /two_factor_authentication/recovery_codes/:id/edit(.:format) two_factor_authentication/recovery_codes#edit {:host=>"571e-77-222-242-230.eu.ngrok.io"}
edit_two_factor_authentication GET /two_factor_authentication/edit(.:format) two_factor_authentications#edit {:host=>"571e-77-222-242-230.eu.ngrok.io"}
edit_two_factor_admin_admin_user GET /admin/admin_users/:id/edit_two_factor(.:format) admin/admin_users#edit_two_factor {:host=>"571e-77-222-242-230.eu.ngrok.io"}
test code:
class AdminUsersControllerTest < ActionDispatch::IntegrationTest
test 'can setup 2FA for admin user' do
admin_user = create(:admin_user)
get edit_two_factor_admin_admin_user_path(admin_user)
assert_template 'admin/admin_users/show_two_factor'
end
end
RAILS_ENV=test rails routes | grep edit_two_factor
edit_two_factor_authentication_confirmation GET /two_factor_authentication/confirmation/edit(.:format) two_factor_authentication/confirmations#edit {:host=>"prograils.io"}
edit_two_factor_authentication_recovery_code GET /two_factor_authentication/recovery_codes/:id/edit(.:format) two_factor_authentication/recovery_codes#edit {:host=>"prograils.io"}
edit_two_factor_authentication GET /two_factor_authentication/edit(.:format) two_factor_authentications#edit {:host=>"prograils.io"}
edit_two_factor_admin_admin_user GET /admin/admin_users/:id/edit_two_factor(.:format) admin/admin_users#edit_two_factor {:host=>"prograils.io"}

Rails 5 Integration test fails with NoMethodError: undefined method `[]=' for nil:NilClass when using Devise helper sign_in

I'm writing an integration test for Rails v5.1 using built-in Minitest.
Here's the integration test class:
require 'test_helper'
class PuppiesEndpointsTest < ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers
test "DELETE puppy" do
marty = people(:marty)
sign_in(marty)
# delete puppies_delete_path(marty.puppies.first.id)
# delete `/api/v1/puppies/destroy/${marty.puppies.first.id}.json`
# delete puppies_path(marty.puppies.first.id)
delete '/api/v1/puppies/destroy/6666.json'
assert_response :success
end
end
All of the routes above, including the ones that are commented out, result in the same cryptic error:
Error:
PuppiesEndpointsTest#test_DELETE_puppy:
NoMethodError: undefined method `[]=' for nil:NilClass
test/integration/puppies_endpoints_test.rb:17:in `block in <class:PuppiesEndpointsTest>'
bin/rails test test/integration/puppies_endpoints_test.rb:7
It doesn't give a stack trace or any other information to diagnose what the hell it's talking about. I used byebug to debug the marty variable right before that delete line that's throwing the error. It shows the expected puppies array of associated (fixture) records.
I've also placed a byebug at the very top of the controller action and this error fails the test before it reaches that byebug, so I think that pretty much rules out anything in the action code.
Here's the relevant chunk of what I see when I run rake routes:
PATCH /api/v1/puppies/edit/:id(.:format) puppies#update
DELETE /api/v1/puppies/destroy/:id(.:format) puppies#destroy
puppies_create POST /api/v1/puppies/create(.:format) puppies#create
Here's what is actually in the my routes file:
scope '/api' do
scope '/v1' do
devise_for :people
patch 'puppies/edit/:id' => 'puppies#update'
delete 'puppies/destroy/:id' => 'puppies#destroy'#, as: 'puppies_delete'
post 'puppies/create' => 'puppies#create'
...
I'm completely stumped as to what/why I'm getting this error. The actual code is working completely as expected.
My hunch is that maybe there's a missing config variable that's not getting set for the test environment (I use dotenv gem), but I have no idea how to track that down if the error won't give me any context whatsoever.
UPDATE
I have isolated this problem to using the Devise helper sign_in method. When I remove this method call, the problem goes away.
Here's the problematic test class:
require 'test_helper'
class PuppiesEndpointsTest < ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers
test "do stuff" do
...
app/controllers/api_controller.rb:
class ApiController < ActionController::API
end
Maybe sign_in does not work for testing controllers that do not inherit from ActionController::Base
I changed the controller to inherit from ActionController::Base and nothing changed. I still can't use sign_in without getting that error, but it works find if I "manually" post a request to the sign_in endpoint.
UPDATE 2
I found this Devise issue which sounds related to my problem: https://github.com/plataformatec/devise/issues/2065
Looks like I found the issue. Apparently, in rails-api mode, the ActionDispatch::Cookies and ActionDispatch::Session::CookieStore middlewares are inserted in the end of the middleware stack, which doesn't occur in normal Rails mode.
Due to this, those middlewares are included after Warden::Manager which messes up something in request specs.
Try to set in test.rb
Rails.application.config.middleware.insert_before Warden::Manager, ActionDispatch::Cookies
Rails.application.config.middleware.insert_before Warden::Manager, ActionDispatch::Session::CookieStore

Can't modify frozen Array error when running rspec

Had been in the process of getting a Rails Engine upgraded to Rails 5.1 and now in the process of getting the rspec tests back working.
I have a controller, and in that controller I have the following:
module Users
class SessionsController < Devise::SessionsController
skip_before_action :authenticate_user!
skip_before_action :authorize_user!
def create
super
flash[:analytics] = { "data-analytics-form-completed-name" => "#{StewardshipUser.app_slug}/sign-in", "data-analytics-form-completed-type" => "login" }
end
def repopulate_email
(params[:user] && params[:user][:email]) ? params[:user][:email] : ''
end
helper_method :repopulate_email
end
end
If I remove the skip_before_action :authorize_user! the tests run, but not all successfully.
With the line I'm getting the following error:
An error occurred while loading ./spec/validators/rfc_compliant_validator_spec.rb.
Failure/Error: Dummy::Application.initialize!
RuntimeError:
can't modify frozen Array
# /Users/ahcarpenter/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/engine.rb:579:in `unshift'
# /Users/ahcarpenter/.rvm/gems/ruby-2.2.2/gems/railties-5.1.4/lib/rails/engine.rb:579:in `block in <class:Engine>'
Any thoughts on why the initializer would be breaking down with that line in there?
Additionally, when I had initially gone to reinitialize rspec, I had to comment out that method to get the initializer to run as it was not found any longer for some reason (I don't seem to have bumped any gem versions up that contained that method, but maybe so)
I'm sure you've fixed this by now, but I had this error, I realized that my test database was not initialized properly. I fixed the error by running the following command:
rails db:migrate RAILS_ENV=test
I hope this is helpful for anyone who stumbles across this post.

Errors RSpec while testing API

just starting to learn RSpec and TDD, and can't figure out why it's don't work at all.
#spec/api/event_api_spec.rb
describe 'Messages API' do
it 'check response' do
get 'api.mydomain.dev/events'
json = JSON.parse(response.body)
# test for the 200 status-code
expect(response).to be_success
end
end
I have create my API on api.mydomain.dev and my folder structure looks like app/controllers/api/events_controller.rb
So when I tried to run bundle exec rspec it's shown that
NoMethodError:
undefined method `get' for #<RSpec::ExampleGroups::MessagesAPI:0x007fc34900cee0>
if I'm trying to make smth like Event.creat!(:name => 'My Event') in My Spec file #spec/api/event_api_spec.rb it says
NameError:
uninitialized constant Event
So i don't understand How require my app/controllers/api/events_controller.rb file to the Spec file to get instance of my Event Class to get it work.
With default controllers it's work fine, I only interesting in API setup, thx
"get" is a method available on controller specs, try with something like
describe 'Messages API', type: :controller do
to tell rspec you are testing something like a controller, or maybe just do
describe EventsController do
About the "uninitialized constant Event", try with this at the begning of spec/api/event_api_spec.rb
require 'rails_helper'
Hope this helps, but your post is a little confusing, is not clear if your api is online or what, you shouldn't test agains the online api, you should test locally, specs should never communicate with the real world unless it's really really necessary.

minitest-spec-rails went wrong when I make some functional test

in my Gemfile:
group :test do
gem 'minitest-spec-rails'
end
my test file in rail_root/test/functional/publisher_controller_test.rb
# -*- encoding : utf-8 -*-
describe PublisherController do
describe "GET #signin" do
it "responds successfully with an HTTP 200 status code" do
get :signin
assert_response :success
end
end
end
my unit test worked fine, but when I run
ruby -Itest test\functional\publisher_controller_test.rb"
it went wrong , here is the error:
test/functional/publisher_controller_test.rb:2:in `<main>':
uninitialized constant PublisherController (NameError).
I just don't know why it can find my model but can not find the controller.
Rails expects controller names to be plural, like so:
PublishersController
Your test is using a singular controller name, PublisherController, which doesn't exist. This can be caused by a typo when using generators.
To fix it, change Publisher to Publishers. Remember to change the filename as well.

Resources