Ruby on Rails Rspec is using the wrong environment and database

Viewed 561

This one has me baffled a bit.

Brand new Rails 6.1.3, Ruby 2.7.0 application with Rspec and database_cleaner

After setting up the application and Rspec, I just created a quick unit test for the User model and then one quick request test to check the default root page.

The first issue I ran into was my request test failing. Instead of displaying the root page which simply has an h1 tag with Home inside of it, the request was returning an error message about www.example.com being a blocked host and to add example.com as into config.hosts

This is the very first time I encountered that and I have another application I created not so long ago with Rails 6.1 and Ruby 2.6.4 and essentially the same configuration but never had this blocked host issue show up.

So I went and added example.com to config.hosts in my test.rb environment. Same issue. I went and added it into development.rb environment file and it passed. This should have been my first red flag.

After toying with my application in development mode and testing the user sign up, adding, deleting users. I ran my test suite again and then found out all the data I had toyed with in development was gone. So I realzed that Rspec was actually running in development environment and running on my development database. Even though my rails_helper.rb file does have the ENV['RAILS_ENV'] ||= 'test' line.

The only way I can get this to run properly is to explicitely run my rspec like so: RAILS_ENV="test" bundle exec rspec spec/requests/pages_spec.rb

But I've never had to do this. Not even in the application I recently created. So it this something new out of Rails 6.1.3? Or perhaps a newer version or Rspec?

Has anyone encountered anything like that? What puzzles me is that both Rails applications were created perhaps a few months apart and other than the Ruby version and the Rails version being different, the other gems are pretty much the same.

Here are the details of the particular files

Gemfile

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.7.0'
gem 'rails', '~> 6.1.3'
gem 'pg', '~> 1.1'
gem 'puma', '~> 5.0'
gem 'sass-rails', '>= 6'
gem 'webpacker', '~> 5.0'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.7'
gem 'bootsnap', '>= 1.4.4', require: false
gem 'devise', '~> 4.7', '>= 4.7.3'
gem 'interactor', '~> 3.0'
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
gem 'faker'

group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'factory_bot_rails', '6.1.0'
  gem 'rspec-rails', '4.0.2'
  gem 'spring-commands-rspec'
end

group :development do
  gem 'web-console', '>= 4.1.0'
  gem 'rack-mini-profiler', '~> 2.0'
  gem 'listen', '~> 3.3'
  gem 'spring'
end

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

group :test do 
  gem 'capybara', '3.35.0'
  gem 'selenium-webdriver', '3.142.6'
  gem 'database_cleaner'
  gem 'geckodriver-helper'
  gem 'webdrivers', '4.1.2'
end

rails_helper.rb

require 'spec_helper'
require 'factory_bot_rails'
require 'devise'
require 'database_cleaner'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'

Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }



begin
  ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
  puts e.to_s.strip
  exit 1
end
RSpec.configure do |config|

  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = true
  config.include FactoryBot::Syntax::Methods
  config.include ControllerMacros, type: :request
  config.include Features::SessionHelpers, type: :feature
  config.include Devise::Test::IntegrationHelpers, type: :request
  config.include Devise::Test::IntegrationHelpers, type: :view
  config.include Devise::Test::IntegrationHelpers, type: :feature
  config.include Warden::Test::Helpers

  config.before(:suite) do 
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.around(:each) do |example|
    DatabaseCleaner.cleaning do 
      example.run 
    end
  end

  config.after(:each) do 
    Warden.test_reset!
  end

  config.infer_spec_type_from_file_location!

  config.filter_rails_from_backtrace!

  Capybara.javascript_driver = :selenium_chrome 

  FactoryBot::SyntaxRunner.class_eval do
    include ActionDispatch::TestProcess
    include ActiveSupport::Testing::FileFixtures
  end
end

database.yml

# PostgreSQL. Versions 9.3 and up are supported.

default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000

development:
  <<: *default
  database: trunfo_development
  host: localhost
  pool: 5
  username: <%= ENV.fetch("DB_USER") %> 
  password: <%= ENV.fetch("DB_PASSWORD") %>

test:
  <<: *default
  database: trunfo_test
  host: localhost
  pool: 5
  username: <%= ENV.fetch("DB_USER") %> 
  password: <%= ENV.fetch("DB_PASSWORD") %>

2 Answers

try setting ENV['RAILS_ENV'] ||= 'test' in project_name/test/test_helper.rb

Perhaps somewhere RAILS_ENV is already being set to something other than "test". Have you tried to print out the env to see? Does writing ENV['RAILS_ENV'] = 'test' in your helper file make a difference?

Related