I'm trying to do functional testing and need to login with Warden.
I have done:
class ActionController::TestCase
include Warden::Test::Helpers
end
My test case is simple:
def test_access_admin_as_superuser
login_as(Person.make(:superuser))
get :index
assert_response :success
assert_nil flash[:warning]
end
I do a login_as(user) and it seems to work except when I do a get '/admin' it will fail with:
1) Error:
test_access_admin_as_superuser(AdminControllerTest):
NoMethodError: undefined method `user' for nil:NilClass
/home/silas/.rubygems/gems/gems/rails_warden-0.5.2/lib/rails_warden/controller_mixin.rb:21:in `current_user'
app/controllers/application_controller.rb:100:in `require_user'
test/functional/admin_controller_test.rb:20:in `test_access_admin_as_superuser'
any ideas?
Devise has helpers to deal with this, which is of little help if you're just using Warden. The reason things break is because action controller sets things up in the test environment in a different way. I put together a little gem that provides a module you can include for working with warden with rails in test mode: github.com/ajsharp/warden-rspec-rails.
Related
I'm trying to get started with controller tests, and I'm not sure what I'm doing wrong. Here's my code, and the error it's producing:
require 'test_helper'
class InvProcure::UserImportsControllerTest < ActionDispatch::IntegrationTest
include Devise::Test::ControllerHelpers
test "should get index" do
user = users(:foobars_admin)
sign_in(:user, user)
get inv_procure_user_imports_path
assert_response :success
end
end
NoMethodError: undefined method `env' for nil:NilClass
/home/blaine/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/devise-4.7.1/lib/devise/test/controller_helpers.rb:42:in `setup_controller_for_warden'
It looks like the error might be happening when including devise test helpers, or when calling sign_in.
From the doc: https://www.rubydoc.info/gems/devise/Devise/Test/ControllerHelpers
Devise::Test::ControllerHelpers provides a facility to test controllers in isolation when using ActionController::TestCase allowing you to quickly sign_in or sign_out a user. Do not use Devise::Test::ControllerHelpers in integration tests.
You are inheriting the integration test class instead of the controller test class which is the default for controller tests now (From Rails 5 the controller tests are generated with the parent class as ActionDispatch::IntegrationTest instead of ActionController::TestCase). Devise::Test::ControllerHelpers was built for ActionController::TestCase and not for integration tests.
You can instead try to use Devise::Test::IntegrationHelpers which should have similar methods for integration tests.
Document: https://www.rubydoc.info/gems/devise/Devise/Test/IntegrationHelpers
I am trying to make some functional tests against new functionality in an application that uses Spree.
The problem that I am running into is that when I launch my created test, the path variables that should exists are not there for the test to execute.
Say I have these routes in my local routes.rb:
Spree::Core::Engine.routes.draw do
namespace :admin do
resources :image_games
end
end
Now in my test I would have the following:
require 'test_helper'
module Spree
module Admin
class ImageGamesControllerTest < ActionController::TestCase
test 'Should get index' do
get admin_image_games_path
assert_response :success
end
end
end
end
What happens is that a Minitest::UnexpectedError: NameError: undefined local variable or methodadmin_image_games_path'` error will be thrown.
I found some advice about this but all of the solutions seem to be for RSpec. I would like to keep using Test::Unit as I feel more at home with it.
So my question, how to load in routes from a foreign Rails Engine into functional tests?
EDIT:
It seems that just the helpers are not working for my tests.
Using get '/store/admin/image_games' works but get admin_image_games_path does not. When running the application normally then these helpers do work tough.
I'm having issues now that i've added devise to my web app, theres a few SO questions on this but they just all point to a readme file and don't actually provide any fixes. I've had to include devise helpers as shown below in order to remove an issue saying the authentication method didn't exist
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
# Add more helper methods to be used by all tests here...
include Devise::TestHelpers
end
If i don't include it i end up with a huge amount of authentication errors:
ActionView::Template::Error: undefined method `authenticate' for nil:NilClass
but if it is included
NoMethodError: undefined method `env' for nil:NilClass
Simply occurs in different places instead, is there an actual fix?
Example
ContactMailerTest#test_should_return_contact_email:
NoMethodError: undefined method `env' for nil:NilClass
Method:
test "should return contact email" do
mail = ContactMailer.contact_email("Email#Email.com", "Example",
"SomeExample", #comment = "Hello")
assert_equal ['info#mynotes.com'], mail.to
assert_equal ['info#mynotes.com'], mail.from
end
This appears to be an issue with "Apparently there are issues with Devise::TestHelpers and integration testing" i am wondering if there is any known fix
Thanks!
I am using devise configured to use omniauth facebook sign in integration.
When calling the sign_in method from my spec/request tests I get:
undefined method `env' for nil:NilClass
spec:
describe FacebookController do
include Devise::TestHelpers
it "should display facebook logged in status" do
#user = User.create(:id => "123", :token => "token")
sign_in #user
visit facebook_path
end
end
Your code looks a lot like mine - I was trying to use Capybara and the Devise TestHelper functions, and it turns out you can't, per https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara. The recommended way to do it is explained on that page, and it worked for me.
To be clear, here's what I did - in spec_helper.rb:
RSpec.configure do |config|
config.include Warden::Test::Helpers
end
Warden.test_mode!
And in my code, simply - logout :user.
Here's why, according to the Devise wiki, you cannot use sign_out:
If you're wondering why we can't just use Devise's built in sign_in and sign_out methods, it's because these require direct access to the request object which is not available while using Capybara. To bundle the functionality of both methods together you can create a helper method.
Which, roughly, means that whereas with, say, MiniTest, an object representing the request (#request) is added as an instance variable to the test case class, that doesn't happen with Capybara. I haven't looked at the code to know the details more exactly but basically, Warden expects to find this object to then access the cookie store where the sign in credentials are. With Capybara/RSpec, I expect this isn't happening.
I'm having some difficulties in testing devise with shoulda:
2) Error:
test: handle :index logged as admin should redirect to Daily page.
(Admin::DailyClosesControllerTest):
NoMethodError: undefined method `env' for nil:NilClass
devise (1.0.6) [v] lib/devise/test_helpers.rb:52:in
`setup_controller_for_warden'
I have this in my test_helper:
include Devise::TestHelpers
Thoughts ?
Thanks in advance,
Cristi
include Devise::TestHelpers doesn't go in the test_helper.rb file, but rather inside the scope of the individual testing classes. Just like their README shows:
class ActionController::TestCase
include Devise::TestHelpers
end
I'm not sure if rspeicher is fully correct, but putting:
class ActionController::TestCase
include Devise::TestHelpers
end
at the very bottom of test_helper.rb (yes after the END of the class ActiveSupport::TestCase) should work. It has for 3 or 4 projects of mine so far, including one i'm working on today.
You then can use sign_in users(:one) if you are using fixtures, in your tests. Unless shoulda is messing it up?