UPDATE: This turned out not to be about my database at all, but rather about preferences stored by Spree in a memory cache that was polluted by my tests. See my answer below.
I am running a Spree application on Rails 3.1.4, with Ruby 1.9.3-p0, rspec-rails 2.8.1, rspec 2.8.0.
Rspec is interacting oddly with Webrick on my development machine, making me think that it is somehow making a running Webrick instance switch to using the test database.
I have one spec for my HomeController:
require 'spec_helper'
describe HomeController do
render_views
describe "GET 'index'" do
it "should be successful" do
get 'index'
response.should be_success
end
end
end
When I boot up Webrick on my localhost (development machine), my home page works fine in the browser. The first time I run Rspec on my HomeController, whose index action corresponds to the home page, my test passes.
After Rspec runs, the page breaks in Webrick because a database field, previously populated with text data, is now nil. Subsequent Rspec iterations also break.
So, is Rspec making Webrick stop using my development database and start using my test database, and why? Is it the ENV["RAILS_ENV"] ||= 'test'
line in spec_helper.rb?
(Here is my spec_helper.rb and sanitized database.yml:)
spec_helper.rb (I have Spork and Autotest installed, but this error occurs when I am not running them too.)
require 'rubygems'
require 'spork'
#uncomment the following line to use spork with the debugger
#require 'spork/ext/ruby-debug'
Spork.prefork do
# Loading more in this block will cause your tests to run faster. However,
# if you change any configuration or code from libraries loaded here, you'll
# need to restart spork for it take effect.
# This file is copied to ~/spec when you run 'ruby script/generate rspec'
# from the project root directory.
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
# require 'capybara/rspec'
# Requires supporting files with custom matchers and macros, etc,
# in ./support/ and its subdirectories.
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
#require 'factories'
RSpec.configure do |config|
# == Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
config.mock_with :rspec
config.fixture_path = "#{::Rails.root}/spec/fixtures"
#config.include Devise::TestHelpers, :type => :controller
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, comment the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
end
@configuration ||= AppConfiguration.find_or_create_by_name("Default configuration")
PAYMENT_STATES = Payment.state_machine.states.keys unless defined? PAYMENT_STATES
SHIPMENT_STATES = Shipment.state_machine.states.keys unless defined? SHIPMENT_STATES
ORDER_STATES = Order.state_machine.states.keys unless defined? ORDER_STATES
# Usage:
#
# context "factory" do
# it { should have_valid_factory(:address) }
# end
RSpec::Matchers.define :have_valid_factory do |factory_name|
match do |model|
Factory(factory_name).new_record?.should be_false
end
end
end
Spork.each_run do
# This code will be run each time you run your specs.
end
database.yml
development:
adapter: mysql2
host: localhost
database: <APP>_development
username: <USER>
password: <PASSWORD>
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: mysql2
host: localhost
database: <APP>_test
username: <USER>
password: <PASSWORD>
production:
adapter: mysql2
host: localhost
database: <APP>_prod
username: <PROD_USER>
password: <PROD_PASSWORD>
It turns out that this was an issue with preferences stored in a cache, and NOT with the databases.
Josh Jacobs answers it (and explains it very well) here
The solution is to configure a different cache store for test and development. In test.rb I added config.cache_store = :memory_store, restarted spork, and everything works.