Factory_girl and RSpec: undefined method `new' for Test:Module - ruby-on-rails

I generated the following scaffold (using Ruby 2.2.0, rails 4.1.8, postgres):
rails g scaffold Test user:references text:references data:hstore
In my test_spec.rb:
require 'rails_helper'
RSpec.describe Test, :type => :model do
describe 'User generates a test' do
before do
#text = create(:text, content: "Cats eat mice")
#user = create(:user)
#test = create(:test)
end
...
When I run rspec the test fails with the following message:
Failure/Error: #test = create(:test)
NoMethodError:
undefined method `new' for Test:Module
# ./spec/models/test_spec.rb:8:in `block (3 levels) in <top (required)>'
When I test other models (user, text) everything works well, only the Test model fails. Calling Test.create(...) in rspec file also fails. Creating new test in rails console works. Any ideas how to fix this?

With the default configuration, Rails defines the module constant Test, so Ruby doesn't autoload your test.rb file when FactoryGirl does a Test.new as part of your :test factory.
You can install Rails without the Test infrastructure by using the -T switch, in which case it won't define the Test module and you should be fine.
If Rails is already configured, you can put the following in your rails_helper.rb file to remove the Test constant and you should be ok as well:
Object.send(:remove_const, :Test)

Related

Rails 6 Integration test exception is too long

I have just set up a brand new rails 6.1 application on Ruby 3.0.
Everything is working as expected, except for the IntegrationTest.
Whenever there's a error in the test, the stack trace is gigantic and unreadable. I'm not sure if it's a wrong config or a bug. It's so long it doesn't fit VSCode terminal. I had to pop up a system terminal to be able to go to the first line of the stack trace and understand what's going on
Here's an snippet of the stack trace:
rails test test/controllers/api/v1/sessions_controller_test.rb:23
E
Error:
API::V1::SessionsControllerTest#test_it_generates_token_on_successfull_auth:
NameError: undefined local variable or method `password' for #<API::V1::SessionsControllerTest:0x000000012d5d6ca8 #_routes=nil, #NAME="test_it_generates_token_on_successfull_auth", #failures=[#<Minitest::UnexpectedError: Unexpected exception>], #assertions=0, #integration_session=#<#<Class:0x0000000107222768>:0x00000001072221a0 #_routes=nil, #app=#<OcaServer::Application:0x000000011db277d0 #_all_autoload_paths=["/Users/joao/code/one_cent_auction/oca_server/app/channels", "/Users/joao/code/one_cent_auction/oca_server/app/controllers", "/Users/joao/code/one_cent_auction/oca_server/app/controllers/concerns", "/Users/joao/code/one_cent_auction/oca_server/app/helpers", "/Users/joao/code/one_cent_auction/oca_server/app/jobs", "/Users/joao/code/one_cent_auction/oca_server/app/mailers", "/Users/joao/code/one_cent_auction/oca_server/app/models", "/Users/joao/code/one_cent_auction/oca_server/app/models/concerns", "/Users/joao/code/one_cent_auction/oca_server/app/services"], #_all_load_paths=["/Users/joao/code/one_cent_auction/oca_server/lib", "/Users/joao/code/one_cent_auction/oca_server/vendor", "/Users/joao/code/one_cent_auction/oca_server/app/channels", "/Users/joao/code/one_cent_auction/oca_server/app/controllers", "/Users/joao/code/one_cent_auction/oca_server/app/controllers/concerns", "/Users/joao/code/one_cent_auction/oca_server/app/helpers", "/Users/joao/code/one_cent_auction/oca_server/app/jobs", "/Users/joao/code/one_cent_auction/oca_server/app/mailers", "/Users/joao/code/one_cent_auction/oca_server/app/models", "/Users/joao/code/one_cent_auction/oca_server/app/models/concerns", "/Users/joao/code/one_cent_auction/oca_server/app/services"], #app=#<ActionDispatch::HostAuthorization:0x000000010f88e5b8 #app=#<Rack::Sendfile:0x000000010f88e770 #app=#<ActionDispatch::Static:0x000000012d407350 #app=#<ActionDispatch::Executor:0x000000012d407490 #app=#<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x000000011dc782d8 #name="ActiveSupport::Cache::Strategy::LocalCache", #local_cache_key=:active_support_cache_null_store_local_cache_4540, #app=#<Rack::Runtime:0x000000012d4076c0 #app=#<Rack::MethodOverride:0x000000012d407800 #app=#<ActionDispatch::RequestId:0x000000012d407a30 #app=#<ActionDispatch::RemoteIp:0x000000012d407b98 #app=#<Rails::Rack::Logger:0x000000012d407cd8 #app=#<ActionDispatch::ShowExceptions:0x000000012d407dc8 #app=#<ActionDispatch::DebugExceptions:0x000000012d407ee0 #app=#<ActionDispatch::
It goes on for thousands of lines.
Here's my test_helper
ENV['RAILS_ENV'] ||= 'test'
require_relative "../config/environment"
require "rails/test_help"
require 'webmock/minitest'
class ActiveSupport::TestCase
include FactoryBot::Syntax::Methods
# Run tests in parallel with specified workers
parallelize(workers: :number_of_processors)
# 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...
end
On another project that I am working on there was never an stacktrace that was that big.
-- Edit
Just to clarify what's triggering the error:
require 'test_helper'
class API::V1::SessionsControllerTest < ActionDispatch::IntegrationTest
setup do
#password = Faker::Internet.password
#user = create(:user)
#user.update! password: password, password_confirmation: password
end
#...
end
The error is happening because I called a variable that hasnt been declared. password instead of #password
The problem is that I was expecting the stack trace to be as simple as:
API::V1::SessionsControllerTest#test_it_generates_token_on_successfull_auth:
NameError: undefined local variable or method `password' for #<API::V1::SessionsControllerTest:0x000000012d5d6ca8>
And not show the entire content of the SessionsControllerTest class.
Is that a normal Rails 6.1 behavior on Ruby 3? I don't recall it happening on Ruby 2.
Here's what I was expecting, reproducing the same error on a Ruby 2, Rails 6.1 application:
rails test test/controllers/jobs_controller_test.rb:15
E
Error:
JobsControllerTest#test_should_get_index:
NameError: undefined local variable or method `it_will_fail' for #<JobsControllerTest:0x0000000115b7c620>
test/controllers/jobs_controller_test.rb:6:in `block in <class:JobsControllerTest>'
test/test_helper.rb:24:in `run'

Gettting undefined method `empty?' for nil:NilClass in my test suite when I try to call a Rails path helper (*_path) using Rails, Rspec

Rails 6.1.3.1
Rspec
basic behavior spec code:
describe "index" do
it "should show me the list" do
visit dashboard_targets_path
end
end
the routes file
namespace :dashboard do
resources :targets
end
error shows me the exception, but strangely it appears as if it isn't calling through to the app, just fails right in my test code:
1) interaction for Dashboard::TargetsController index should show me the list
Failure/Error: visit dashboard_targets_path
NoMethodError:
undefined method `empty?' for nil:NilClass
# ./spec/system/dashboard/targets_behavior_spec.rb:16:in `block (3 levels) in <top (required)>'
# /Users/jason/.rvm/gems/ruby-2.6.6/gems/webmock-3.12.2/lib/webmock/rspec.rb:37:in `block (2 levels) in <main>'
# /Users/jason/.rvm/gems/ruby-2.6.6/gems/rspec-wait-0.0.9/lib/rspec/wait.rb:46:in `block (2 levels) in <main>'
it seems to be failing inside the test code, if I drop into the debugger there and run dashboard_targets_path directly I also get the same exception, so the problem is just using the helper within the TEST ENVIRONMENT
within the dev environment, this function works
the problem here was the the config/environments/test.rb file does have default_url_options.
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
when you hit errors that disappear into the Rails gems, a good way to debug them is like so:
begin
// your failing code here
rescue StandardError => e
puts e.backtrace
byebug
puts e.inspect
raise (e)
end
WARNING: do not leave this code in your app or check it in unless you explicitly want to use exception handling for flow control (not recommended!). This is recommended ONLY for debugging purposes.
here you will see the full backtrace to the line number in the Gem where it is failing. when debugging Gems be careful— remember to un-do any changes you make and know that your monkey-patching inside of the Gem code doesn't affect your production code.

Rspec 'it { should have_db_column(:x).of_type(:y) }' not working

My attendance_rspec.rb file contains:
require "rails_helper"
RSpec.describe Attendance, type: :model do
it { should have_db_column(:date).of_type(:date) }
end
When I run it from the terminal using rspec spec/models/attendance_spec.rb
It shows the error:
Failures:
1) Attendance
Failure/Error: it { should have_db_column(:date).of_type(:date) }
NoMethodError:
undefined method `of_type' for #<RSpec::Matchers::BuiltIn::Has:0x000055e5c65dd3e0>
# ./spec/models/attendance_spec.rb:4:in `block (2 levels) in <main>'
I already have FactoryBot configured along with database_cleaner and capybara gems. What gem am I missing or any config missing in rails_helper.rb?
I followed this link for setting up Rspec
As NickM pointed out, the have_db_column matcher is provided by the shoulda-matchers gem. Add it to your Gemfile and follow the integration steps to use have_db_column.

Devise 3.2 + Rspec 3

I'm trying to build some tests with Rspec and I'm getting the following error:
Failure/Error: get :index
NoMethodError:
undefined method `authenticate!' for nil:NilClass
Then I made some searchs and I realized that I had to include this line in the spec_helper.rb:
RSpec.configure do |config|
config.include Devise::TestHelpers, type: :controller
end
It seems that this code worked for most people but not for me. Now i'm getting the following error:
/home/bruna/Dropbox/Rails/academico/spec/spec_helper.rb:18:in `block in <top (required)>': uninitialized constant Devise (NameError)
I think this might be some error in this version of rspec and/or devise. Has anyone seen this error? Please, help me :'(
RSpec 3 configuration is different from earlier versions, with the addition of a spec/rails_helper.rb file that must be included for each spec file. Add the Devise TestHelpers to the spec/rails_helper.rb file.
If you need more information about RSpec 3 configuration, I've written an RSpec Tutorial. There's also information about testing Devise with RSpec, including advice about session helpers for feature testing, in my Rails Devise Tutorial.

Factory Girl undefined method for nil:NilClass

I have a controller spec something like this
describe :bizzaro_controller do
let(:credit_card_account) { FactoryGirl.build :credit_card_account }
it "doesn't blow up with just the stub" do
CreditCardAccount.stub(:new).and_return(credit_card_account)
end
it "doesn't blow up" do
credit_card_account
CreditCardAccount.stub(:new).and_return(credit_card_account)
end
end
Which results in this:
bizzaro_controller
doesn't blow up with just the stub (FAILED - 1)
doesn't blow up
Failures:
1) bizzaro_controller doesn't blow up
Failure/Error: let(:credit_card_account) { FactoryGirl.build :credit_card_account }
NoMethodError:
undefined method `exp_month=' for nil:NilClass
# ./spec/controllers/user/bizzareo_controller_spec.rb:5:in `block (2 levels) in <top (required)>'
# ./spec/controllers/user/bizzareo_controller_spec.rb:9:in `block (3 levels) in <top (required)>'
Finished in 0.23631 seconds
2 examples, 1 failure
My credit card factory looks like this:
FactoryGirl.define do
factory :credit_card_account do
exp_month 10
exp_year 2075
number '3'
end
end
My CreditCardAccount is an empty ActiveRecord::Base model
=> CreditCardAccount(id: integer, exp_month: integer, exp_year: integer, number: string)
Versions
0 HAL:0 work/complex_finance % bundle show rails rspec-rails factory_girl
/home/brundage/.rvm/gems/ruby-2.0.0-p247#complex_finance/gems/rails-4.0.0
/home/brundage/.rvm/gems/ruby-2.0.0-p247#complex_finance/gems/rspec-rails-2.14.0
/home/brundage/.rvm/gems/ruby-2.0.0-p247#complex_finance/gems/factory_girl-4.2.0
This should be working. all points that your test database is not correct.
RAILS_ENV=test rake db:drop db:create will drop and recreate your test database. Then try to run your rspec using the rake command, in order to migrate the database: rake rspec
I was having the same problem, but I think the cause of my problem was different. My solution, however, may perhaps be useful: I used the Fabrication gem (http://www.fabricationgem.org/) instead of FG.
The reason why I was having this problem was because I was trying to have FG create/build an object that was not ActiveRecord, it was only an ActiveModel, and it had to be initialized with arguments.
I didn't see in the Fabricator documentation an example totally like what I needed, but I got it with this syntax:
Fabricator(:my_class) do
on_init do
init_with("Company Name", "Fake second arg")
end
end
My problem was that in model I made a private method called :send (forgot that it is already used in Ruby).

Resources