Reputation: 4595
All 211 specs in my test suite were passing fine...until I upgraded from rails 3.2 to rails 3.2.1. Now 197 of my specs fail with errors. Most of these error have the "wrong number of arguments (0 for 1)" error described below.
Example #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
Spec:
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
Fails with:
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)>'
If I place a call to the debugger before the the FactoryGirl.create line, I get:
/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:
Example #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
Fails with:
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)>'
Line 8 in my sessions_controller is:
user = User.find_by_email(params[:email])
Inspecting the params at this point shows everything (including :email) is present as it should be.
Contrasting Example #3
This spec with FactoryGirl passes fine:
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
The factories are defined as follows:
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
If I comment out the FriendlyId lines from the DocumentLibrary model, Example #1 passes. I have no idea why that makes a difference.
However, some specs still don't pass. Consider the following model (which doesn't use FriendlyId) and spec that flunks in 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)>'
Results of: 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)>'
I'm using rvm with ruby 1.9.3, with Rubygems at 1.8.16. Factory Girl is at 2.6.0, with factory_girl_rails at 1.7.0. rspec-rails is at 2.8.1.
Here's what I know so far:
Can anyone point me in a direction on this? Or offer troubleshooting advice?
Here's my 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
The only differences in Gemfile.lock after upgrading to Rails 3.2.1 are with the Rails core libraries (no testing gems changed).
Upvotes: 13
Views: 2614
Reputation: 674
Maybe you should try to create a new gemset, in case some gems are interfering with each other.
$ rvm use 1.9.3@{unique-gemset-name-here} --create
Clean gemset$ bundle
$ rake spec
As I've been following this for the last two days, I'm starting to think if you should just drop the 3.2.1-upgrade for now (given this is a high priority-project). Get the value out to your customer and/or users instead of spending time on 3.2.1. Someone will figure this out sometime and then you can proceed with the upgrade.
Upvotes: 0
Reputation: 674
In the first spec you mention could you add the following to your controller file:
def create
puts params.inspect
user = User.find_by_email(params[:email])
end
I think you're not getting any info from params. And as this is the login_admin
function in spec, it may be that you're using a before(:each)
or let
-block to sign in for most of your specs, so this may be the root of the problem.
Just noticed it now :)
Upvotes: 0
Reputation:
It might be an obsolete syntax in your model. Replace
default_scope order: :title
with
default_scope :order => :title
If I comment out the FriendlyId lines from the DocumentLibrary model, the spec above passes. I have no idea why that makes a difference
With this modification, default_scope order: :title
became the last line of your model
Upvotes: 0
Reputation: 674
First thing you could try (which you haven't according to the list) is simply removing all data from the test DB and "resetting" your test environment. For some reason maybe your DB is full of test data, sequences aren't working and/or migrations haven't been run.
$ rake db:test:prepare
If that doesn't fix the problem, then I'd first make my FactoryGirl-definitions and calls more consistent - not to be rude, but I think I'm seeing 3-4 different variations throughout the code you posted. It also makes it harder to decode the cryptic error messages from the trace - as you're not being consistent with the calls.
Best practice definitions:
FactoryGirl.define do
factory :document_library do
sequence(:title) { |n| "Title #{n}" }
end
end
Best practice building/creation:
document_library = FactoryGirl.create(:document_library, {
title: 'A',
visible: false
})
# or
document_library = FactoryGirl.build(:document_library)
I know you wrote it works in Rails 3.2.0 and everything is Rails 3.2.1 fault, but there probably just an issue with 3.2.1 MIXED with the version you're using of RSpec and FactoryGirls. According to the Changelog there hasn't been any changes to the ActiveRecord module in Rails 3.2.1.
Upvotes: 3
Reputation: 9594
This might not be the root cause, but since your errors hint at FactoryGirl, I'd first convert all factories (and their creation) to another (new/recommended (?)) syntax, i.e. FactoryGirl.define do ...
and doclib = FactoryGirl.create(:document_library ...
. It might be that Factory
is something different when running specs (than what it is in the console).
Upvotes: 2