Почему обновление до Rails 3.2.1 приводит к сбою нескольких тестов Rspec? - PullRequest
13 голосов
/ 14 февраля 2012

Все 211 спецификаций в моем тестовом наборе проходили нормально ... пока я не перешел с rails 3.2 на rails 3.2.1. Теперь 197 моих спецификаций терпят неудачу с ошибками. Большинство из этих ошибок имеют ошибку «неправильное количество аргументов (0 для 1)», описанную ниже.

Пример № 1:

class DocumentLibrary < ActiveRecord::Base
  extend FriendlyId
  friendly_id :title, :use => :slugged
  has_many :shelves, :dependent => :destroy
  has_many :documents, :through => :shelves
  validates :title, :presence => true, :uniqueness => true

  default_scope :order => :title
end

Спецификация:

  it "can be shown on the company menu" do
    dl = FactoryGirl.create(:document_library, :title => 'Test', :menu => false, :company => true)
    dl.should be_valid
  end

Сбой с:

   1) DocumentLibrary can be shown on the company menu
     Failure/Error: dl = FactoryGirl.create(:document_library, title: 'Test', menu: false, company: true)
     ArgumentError:
       wrong number of arguments (0 for 1)
     # ./spec/models/document_library_spec.rb:6:in `block (2 levels) in <top (required)>'

Если я помещаю вызов отладчику до строки FactoryGirl.create, я получаю:

/Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/activesupport-3.2.1/lib/active_support/dependencies.rb:252:
(rdb:1) c
/Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/activesupport-3.2.1/lib/active_support/core_ext/module/remove_method.rb:4: `' (NilClass)
    from /Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:249:in `set_it_up'
    from /Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:200:in `subclass'
    from /Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:187:in `describe'
    from /Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/rspec-core-2.8.0/lib/rspec/core/dsl.rb:18:in `describe'
    from /Users/Jason/code/rails/teamsite/spec/models/document_library_spec.rb:4:in `<top (required)>'
    from /Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/rspec-core-2.8.0/lib/rspec/core/configuration.rb:698:in `load'
    from /Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/rspec-core-2.8.0/lib/rspec/core/configuration.rb:698:in `block in load_spec_files'
    from /Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/rspec-core-2.8.0/lib/rspec/core/configuration.rb:698:in `map'
    from /Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/rspec-core-2.8.0/lib/rspec/core/configuration.rb:698:in `load_spec_files'
    from /Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/rspec-core-2.8.0/lib/rspec/core/command_line.rb:22:in `run'
    from /Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/rspec-core-2.8.0/lib/rspec/core/runner.rb:80:in `run_in_process'
    from /Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/rspec-core-2.8.0/lib/rspec/core/runner.rb:69:in `run'
    from /Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/rspec-core-2.8.0/lib/rspec/core/runner.rb:10:in `block in autorun'
/Users/Jason/.rvm/gems/ruby-1.9.3-p125/gems/activesupport-3.2.1/lib/active_support/core_ext/module/remove_method.rb:4:

Пример № 2

class Album < ActiveRecord::Base
  belongs_to :photo_library

  validates :title, :presence => true
  validates :title, :uniqueness => {scope: :photo_library_id}
end

class PhotoLibrary < ActiveRecord::Base
  default_scope :order => :title
  has_many :albums, :dependent => :destroy

  validates :title, :presence => true
  validates :title, :uniqueness => true
end

Spec:

  before :each do
    @photo_library = FactoryGirl.create(:photo_library, title: 'Products')
    login_admin
  end

  it "destroys an album" do
    3.times { FactoryGirl.create(:album, photo_library: @photo_library) }
    visit photo_library_path(@photo_library)
    find("h3").click_link 'Delete'
    find("#notice").should have_content("Album deleted successfully")
    Album.count.should eq 2
  end

Сбой с:

1) Albums destroys an album
     Failure/Error: login_admin
     ArgumentError:
       wrong number of arguments (0 for 1)
     # ./app/controllers/sessions_controller.rb:8:in `create'
     # (eval):2:in `click_button'
     # ./spec/requests/albums_spec.rb:7:in `block (2 levels) in <top (required)>'

Строка 8 в моем session_controller:

user = User.find_by_email(params[:email])

Проверка параметров на этом этапе показывает, что все (в том числе: электронная почта) присутствует должным образом.

Контрастный пример № 3

Эта спецификация с FactoryGirl проходит нормально:

  it "is unique within a library" do
    pl = FactoryGirl.create(:photo_library, title: 'Products')
    pl2 = FactoryGirl.create(:photo_library, title: 'Competitors')
    a = FactoryGirl.create(:album, title: 'Gold Series', photo_library: pl)
    na = Album.create(photo_library_id: pl.id, title: 'Gold Series')
    na.should_not be_valid
    na.title = 'Cyclone'
    na.should be_valid

    na = Album.create(photo_library_id: pl2.id, title: 'Gold Series')
    na.should be_valid
  end

Заводы определены следующим образом:

  factory :document_library do
    sequence(:title) { |n| "Library Title#{n}" }
  end

  factory :photo_library do
    sequence(:title) { |n| "Photo Library Title#{n}" }
  end

  factory :album do
    sequence(:title) {|n| "Album#{n}"}
  end

Если я закомментирую строки FriendlyId из модели DocumentLibrary, пример №1 будет пройден. Я понятия не имею, почему это имеет значение.

Однако некоторые спецификации все еще не проходят. Рассмотрим следующую модель (которая не использует FriendlyId) и спецификацию, которая работает в 3.2.1:

class DrawingLibrary < ActiveRecord::Base
  validates :title, :presence => true
  default_scope order: :title 
  has_many :drawings, :dependent => :destroy
end

 it "displays in alpha order" do
  FactoryGirl.create(:drawing_library, title: 'C')
  FactoryGirl.create(:drawing_library, title: 'B')
  FactoryGirl.create(:drawing_library, title: 'A')

  ts = ''

  DrawingLibrary.all.each do |draw_lib|
    ts += draw_lib.title
  end

  ts.should eq 'ABC'
end

1) DrawingLibrary displays in alpha order
     Failure/Error: DrawingLibrary.all.each do |draw_lib|
     ArgumentError:
       wrong number of arguments (0 for 1)
     # ./spec/models/drawing_library_spec.rb:19:in `block (2 levels) in <top (required)>'

Результаты: rspec spec / models / document_library_spec.rb --backtrace

 1) DocumentLibrary can be shown on the company menu
 Failure/Error: dl = FactoryGirl.create(:document_library, title: 'Test', menu: false, company: true)
 ArgumentError:
   wrong number of arguments (0 for 1)
 # ./spec/models/document_library_spec.rb:6:in `block (2 levels) in <top (required)>'

Я использую rvm с ruby ​​1.9.3, с Rubygems на 1.8.16. Factory Girl находится на 2.6.0, а factory_girl_rails на 1.7.0. rspec-рельсы в 2.8.1.

Вот что я знаю до сих пор:

  • Понижение до Rails 3.2.0 заставляет все работать снова
  • Обновление до Edge Rails не решает проблему
  • Запуск крайних версий драгоценных камней rspec не решает проблему
  • Приложение работает правильно и в ожидаемом режиме разработки. Похоже, что затронуты только тесты.
  • Понижение до ruby ​​1.9.2 не решает проблему
  • Обновление до ruby ​​1.9.3-p125 не решает проблему
  • Переход с MySQL на SQLite для тестовой среды не решает проблему
  • Понижение factory_girl_rails до 1.6.0 или даже 1.5.0 не решает проблему
  • Использование Factory.create (...) вместо Factory (...) не решает проблему
  • Использование FactoryGirl.define () и FactoryGirl.create () не решает проблему
  • При комментировании материала FriendlyId некоторые спецификации проходят (см. Ниже)
  • Запуск db: test: prepare (или db: reset, db: migrate) не решает проблему
  • Изменение всех определений / созданий FactoryGirl на согласованность не решает проблему
  • Переустановка гемов под новым набором гемов rvm (или даже полная переустановка rvm) не решает проблему
  • Перезапись этих тестов в Test / Unit и FactoryGirl не выдает ошибок. Таким образом, FactoryGirl не может быть проблемой

Может кто-нибудь указать мне направление на это? Или предложить советы по устранению неполадок?

Вот мой Gemfile:

source 'http://rubygems.org'

gem 'rails', '3.2.1'

gem 'mysql2'
gem 'dynamic_form'
gem 'friendly_id'

group :assets do
  gem 'sass-rails', "  ~> 3.2.3"
  gem 'coffee-rails', "~> 3.2.1"
  gem 'uglifier', '>= 1.0.3'
end

gem 'jquery-rails'
gem 'therubyracer'
gem 'bcrypt-ruby'
gem 'capistrano'
gem "paperclip", :git => "git://github.com/thoughtbot/paperclip.git"

group :test, :development do
  gem 'rspec-rails'
  gem 'launchy'
  gem 'ruby-debug19'
  gem 'database_cleaner'
  gem 'capybara-webkit'
  gem 'spork', '~> 0.9.0.rc'
  gem 'guard-spork'
end

group :development do
  gem 'fuubar'
  gem 'powder'
end

group :test do
  gem 'turn', :require => false
  gem 'capybara'
  gem 'factory_girl_rails'
  gem 'guard-rspec'
end

Единственные отличия в Gemfile.lock после обновления до Rails 3.2.1 заключаются в базовых библиотеках Rails (не изменен гем тестирования).

Ответы [ 5 ]

3 голосов
/ 22 февраля 2012

Первое, что вы можете попробовать (чего у вас нет согласно списку), это просто удалить все данные из тестовой БД и «перезагрузить» вашу тестовую среду.По какой-то причине, возможно, ваша БД полна тестовых данных, последовательности не работают и / или миграции не были выполнены.

$ rake db:test:prepare

Если это не решит проблемуЗатем я сначала сделаю свои FactoryGirl-определения и вызовы более согласованными - не хамить, но я думаю, что я вижу 3-4 различных варианта в коде, который вы опубликовали.Это также затрудняет декодирование загадочных сообщений об ошибках из трассировки - поскольку вы не согласны с вызовами.

Определения передового опыта:

FactoryGirl.define do
  factory :document_library do
    sequence(:title) { |n| "Title #{n}" }
  end
end

Построение / создание передового опыта:

document_library = FactoryGirl.create(:document_library, {
  title: 'A',
  visible: false
})
# or
document_library = FactoryGirl.build(:document_library)

Я знаю, что вы написали, что это работает в Rails 3.2.0, и все это ошибка Rails 3.2.1, но, вероятно, только проблема с 3.2.1 MIXED с версией, которую вы используете из RSpecи FactoryGirls.Согласно Changelog в модуле ActiveRecord в Rails 3.2.1 не было никаких изменений.

2 голосов
/ 21 февраля 2012

Это может быть не основной причиной, но поскольку ваши ошибки намекают на FactoryGirl, я сначала преобразовал бы все фабрики (и их создание) в другой (новый / рекомендуемый (?)) Синтаксис, то есть FactoryGirl.define do ... и doclib = FactoryGirl.create(:document_library ....Возможно, Factory - это что-то другое при запуске спецификаций (чем то, что есть в консоли).

0 голосов
/ 24 февраля 2012

Возможно, вам следует попытаться создать новый набор драгоценных камней, если некоторые камни мешают друг другу.

  1. $ rvm use 1.9.3@{unique-gemset-name-here} --create Очистить набор драгоценных камней
  2. $ bundle
  3. $ rake spec

Поскольку я следил за этим в течение последних двух дней, я начинаю думать, стоит ли вам сейчас отказаться от обновления 3.2.1 (учитывая, что этоприоритетный проект).Получите выгоду от своих клиентов и / или пользователей вместо того, чтобы тратить время на 3.2.1.Кто-нибудь когда-нибудь выяснит это, и тогда вы сможете приступить к обновлению.

0 голосов
/ 23 февраля 2012

В первой спецификации, которую вы упомянули, вы могли бы добавить следующее к вашему файлу контроллера:

def create
  puts params.inspect
  user = User.find_by_email(params[:email])
end

Я думаю, что вы не получаете никакой информации от params. А так как это функция login_admin в спецификации, возможно, вы используете before(:each) или let -блок для входа в большинство ваших спецификаций, так что это может быть причиной проблемы.

Просто заметил это сейчас:)

0 голосов
/ 23 февраля 2012

Это может быть устаревший синтаксис в вашей модели.Замените

default_scope order: :title 

на

 default_scope :order => :title 

Если я закомментирую строки FriendlyId из модели DocumentLibrary, приведенная выше спецификация пройдет.Я понятия не имею, почему это имеет значение

С этой модификацией default_scope order: :title стала последней линией вашей модели

...