使用FactoryGirl创建的模型在控制器中不可用

原始问题

我正在尝试用RSpec和Capybara编写一些function测试,并想知道为什么我的gon对象总是空的,尽管它是在我的控制器中设置的:

app/controllers/timetrackings_controller.rb

 class TimetrackingsController  false).order(:number) gon.projects = group_by_customer(projects).to_h gon.services = Service.all_cached.select('id, name').where(:archived => false).order('LOWER(name)') end ... 

现在我想知道为什么这些数据没有呈现到我的视图中(使用save_and_open_page// ),所以我只是试图在我的测试文件中获取gon值:

 require 'spec_helper' describe 'the timetracking page', :js => true do before :each do switch_to_subdomain('test') @project = FactoryGirl.create(:project) @service = FactoryGirl.create(:service) user = FactoryGirl.create(:user) login_as(user, :scope => :user) visit '/timetracking' save_and_open_page end it 'renders the react component' do expect(page).to have_selector '#timetracking-form' end it 'allows me to create a new timetracking' do within('#timetracking-form') do fill_in 'duration', :with => '2' puts '########' puts Gon.all_variables puts Project.all.to_json puts Service.all.to_json puts '########' find_field('project_id').find("option[value='#{@project.id}']").click end click_button '.ei-icon-check' end end 

但输出只是:

 ######## {} [{"id":2,"number":"2","name":"project2","description":"Some notes","archived":false,"customer_id":2,"created_at":"2015-11-30T16:05:40.160+01:00","updated_at":"2015-11-30T16:05:40.160+01:00","rate_type":null,"hourly_rate":null,"service_rates":null,"budget_type":null,"budget_rate":null,"category":"A","deadline":null}] [{"id":2,"name":"service2","description":"Some notes","archived":false,"created_at":"2015-11-30T16:05:40.173+01:00","updated_at":"2015-11-30T16:05:40.173+01:00","billable":null,"hourly_rate":null}] ######## 

那是我的spec_helper.rb

 require 'devise' # Setup Capybara require 'capybara/rspec' require 'capybara/poltergeist' Capybara.always_include_port = true Capybara.javascript_driver = :poltergeist # Use SimpleCov for code coverage require 'simplecov' require 'simplecov-shield' SimpleCov.start 'rails' SimpleCov.formatters = [ SimpleCov::Formatter::HTMLFormatter, SimpleCov::Formatter::ShieldFormatter ] # This file is copied to spec/ when you run 'rails generate rspec:install' ENV['RAILS_ENV'] ||= 'test' require File.expand_path('../../config/environment', __FILE__) require 'rspec/rails' require 'shoulda-matchers' # Requires supporting ruby files with custom matchers and macros, etc, in # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are # run as spec files by default. This means that files in spec/support that end # in _spec.rb will both be required and run as specs, causing the specs to be # run twice. It is recommended that you do not name files matching this glob to # end with _spec.rb. You can configure this pattern with with the --pattern # option on the command line or in ~/.rspec, .rspec or `.rspec-local`. Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } # Checks for pending migrations before tests are run. # If you are not using ActiveRecord, you can remove this line. ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration) module ControllerMacros def attributes_with_foreign_keys(*args) FactoryGirl.build(*args).attributes.delete_if do |k, v| ['id', 'type', 'foreign_id', 'foreign_type', 'created_at', 'updated_at'].member?(k) end end end RSpec.configure do |config| config.use_transactional_fixtures = false config.use_instantiated_fixtures = false config.mock_with :rspec # Use FactoryGirl for fixtures config.include FactoryGirl::Syntax::Methods # Auto-detect spec types config.infer_spec_type_from_file_location! # Insert devise helpers in controller specs config.include Devise::TestHelpers, type: :controller config.include Warden::Test::Helpers config.extend ControllerMacros, type: :controller config.include ControllerMacros # Run specs in random order to surface order dependencies. If you find an # order dependency and want to debug it, you can fix the order by providing # the seed, which is printed after each run. # --seed 1234 config.order = 'random' config.before(:suite) do Warden.test_mode! # Clean all tables to start DatabaseCleaner.clean_with :truncation # Use transactions for tests DatabaseCleaner.strategy = :transaction # Truncating doesn't drop schemas, ensure we're clean here, app *may not* exist Apartment::Tenant.drop('test') rescue nil # Create the default tenant for our tests Account.create!(name: 'Test', domain: 'test', email: 'info@example.com') end config.before(:each) do # Start transaction for this test DatabaseCleaner.start # Switch into the default tenant Apartment::Tenant.switch! 'test' # Use Timecop to freeze times on time-critical tests Timecop.return end config.after(:each) do # Reset tentant back to `public` Apartment::Tenant.reset # Rollback transaction DatabaseCleaner.clean end end 

更新

好吧,我认为问题出在其他地方:

使用FactoryGirl创建模型(如FactoryGirl.create(:project) )后,控制器中的记录不可用。 如果我写的东西像

 @foo = Project.all.to_json 

在我的控制器中,想要在我的视图中显示这些数据,我只是得到[] (在调用save_and_open_page )。

我虽然FactoryGirl.create直接将数据写入数据库? 为什么我的控制器方法中的数据不可用?

更新2

添加

 config.before(:each, :js => true) do DatabaseCleaner.strategy = :truncation end 

解决了这个问题,但现在我得到了:

  Failure/Error: user = FactoryGirl.create(:user) ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_users_on_lastname" DETAIL: Key (lastname)=(Kautzer) already exists. : INSERT INTO "users" ("email", "initial", "firstname", "lastname", "encrypted_password", "archived", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" 

我认为每次测试后数据库都会被清理干净?

更新3

无视,最后一个问题是我的数据库设置错误。

添加

 config.before(:each, :js => true) do DatabaseCleaner.strategy = :truncation end 

到我的spec_helper.rb解决了问题:)