I recently changed laptops and now Rspec doesn't seem to run normally locally.
When I run a simple test:
describe 'price' do
let(:product) { create(:product) }
let(:product_item) { create(:product_item, product_id: product.id) }
it "is half of the retail price if it has never been rented" do
product.update_attributes(sale_price_new: [200_000, 190_000])
product_item.reload
expect(product_item.price(2.days.from_now, "EUR")).to eq(100_000)
end
I get
Failures:
1) ProductItem price is half of the retail price if it has never been rented
Failure/Error: let(:product) { create(:product) }
RestClient::RequestTimeout:
Request Timeout
# ./spec/models/product_item_spec.rb:108:in `block (3 levels) in <top (required)>'
# ./spec/models/product_item_spec.rb:160:in `block (3 levels) in <top (required)>'
# ./spec/spec_helper.rb:85:in `block (2 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# IO::EAGAINWaitReadable:
# Resource temporarily unavailable - read would block
# ./spec/models/product_item_spec.rb:108:in `block (3 levels) in <top (required)>'
But when I run it on the server, or in the previous laptop, everything works fine.
Anyone knows what I'm missing?
Thank you so much!
Related
I have an almost meaningless worker test spec:
require 'rails_helper'
require 'sidekiq/testing'
Sidekiq::Testing.fake!
RSpec.describe FetchArticleContentWorker, type: :worker do
describe "Sidekiq Worker" do
before(:each) do
allow_any_instance_of(DataSource).to receive(:subscribe).and_return(true)
allow_any_instance_of(FetchArticleContentWorker).to receive(:perform).and_return(true)
end
let(:user) { FactoryBot.create(:user) }
let(:data_source) { FactoryBot.create(:data_source) }
let(:article) { FactoryBot.create(:article, data_source_id: data_source.id) }
it "should respond to #perform" do
expect(FetchArticleContentWorker.new).to respond_to(:perform)
end
describe "fetch article content worker" do
before do
Sidekiq::Worker.clear_all
end
it "increase the worker job size" do
expect { FetchArticleContentWorker.perform_async(article.url) }.to change(FetchArticleContentWorker.jobs, :size).by(1)
end
it "assert that jobs were pushed on to the queue" do
assert_equal 0, FetchArticleContentWorker.jobs.size
FetchArticleContentWorker.perform_async(article.url)
assert_equal 1, FetchArticleContentWorker.jobs.size
end
it "job runs successfully" do
expect(FetchArticleContentWorker.new.perform(article.url)).to eq(true)
end
end
end
end
For whatever reason, this set of specs has suddenly started failing but only when run as a part of the entire test suite. If I run this test directly by itself, it passes every time.
When run with bundle exec rspec (to do the whole suite), I get the following failures for this particular test:
Failures:
1) FetchArticleContentWorker Sidekiq Worker fetch article content worker increase the worker job size
Failure/Error: expect { FetchArticleContentWorker.perform_async(article.url) }.to change(FetchArticleContentWorker.jobs, :size).by(1)
expected `Array#size` to have changed by 1, but was changed by 0
# ./spec/workers/fetch_article_content_worker_spec.rb:29:in `block (4 levels) in <top (required)>'
# ./spec/rails_helper.rb:48:in `block (3 levels) in <top (required)>'
# /usr/local/bundle/gems/database_cleaner-1.8.4/lib/database_cleaner/generic/base.rb:16:in `cleaning'
# /usr/local/bundle/gems/database_cleaner-1.8.4/lib/database_cleaner/configuration.rb:87:in `block (2 levels) in cleaning'
# /usr/local/bundle/gems/database_cleaner-1.8.4/lib/database_cleaner/configuration.rb:88:in `cleaning'
# ./spec/rails_helper.rb:47:in `block (2 levels) in <top (required)>'
2) FetchArticleContentWorker Sidekiq Worker fetch article content worker assert that jobs were pushed on to the queue
Failure/Error: assert_equal 1, FetchArticleContentWorker.jobs.size
Minitest::Assertion:
Expected: 1
Actual: 0
# /usr/local/bundle/gems/minitest-5.14.0/lib/minitest/assertions.rb:183:in `assert'
# /usr/local/bundle/gems/minitest-5.14.0/lib/minitest/assertions.rb:218:in `assert_equal'
# ./spec/workers/fetch_article_content_worker_spec.rb:35:in `block (4 levels) in <top (required)>'
# ./spec/rails_helper.rb:48:in `block (3 levels) in <top (required)>'
# /usr/local/bundle/gems/database_cleaner-1.8.4/lib/database_cleaner/generic/base.rb:16:in `cleaning'
# /usr/local/bundle/gems/database_cleaner-1.8.4/lib/database_cleaner/configuration.rb:87:in `block (2 levels) in cleaning'
# /usr/local/bundle/gems/database_cleaner-1.8.4/lib/database_cleaner/configuration.rb:88:in `cleaning'
# ./spec/rails_helper.rb:47:in `block (2 levels) in <top (required)>'
It appears that these worker specs only fail when a feature using turnip is previously run.
I ended up finding what I think is the problem.
In my turnip steps file I was setting sidekick to inline:
# set sidekiq to inline
require 'sidekiq/testing'
Sidekiq::Testing.inline!
And, even though I was setting Sidekiq::Testing.fake! in the above mentioned spec file, it didn't seem to "take".
When I moved fake! into the before block, that seemed to fix the problem:
describe "Sidekiq Worker" do
before(:each) do
allow_any_instance_of(DataSource).to receive(:subscribe).and_return(true)
allow_any_instance_of(FetchArticleContentWorker).to receive(:perform).and_return(true)
Sidekiq::Testing.fake!
end
...
I am not sure why this is the fix, but this fixed it.
I have problems with error message ./spec/models/lib/parsers/s_reality_cz/matcher_spec.rb:12:in `block (2 levels) in ' in every rspec test. What I'm doing wrong? Using rspec-rails 3.5. Thanks
Code:
require 'rails_helper'
RSpec.describe Parsers::SRealityCz::Matcher, :type=> :model do
before do
#doc = File.open("spec/fixtures/srealitycz_profile.html") { |f| Nokogiri::HTML(f) }
end
let(:parser) { described_class }
it "returns total price" do
expect(parser.title(#doc)).to eq "Prodej bytu 1+kk 40 m²"
end
end
Rspec output:
Randomized with seed 37464
expected: "Prodej bytu 1+kk 40 m²"
got: "Prodej bytu 1+kk 40 m²"
(compared using ==)
./spec/models/lib/parsers/s_reality_cz/matcher_spec.rb:12:in `block (2 levels) in <top (required)>'
-e:1:in `load'
-e:1:in `<main>'
1 example, 1 failure, 0 passed
Finished in 0.139173354 seconds
Your strings look the same, but they probably have different encodings.
Convert them both to the same encoding (e.g. UTF-8), and compare them.
I am trying to create two custom rake tasks in in Rails 4 app. They are supposed to read the agent_card table and based on the logic, fire off an email when the time is triggered. This is my first time creating a rake task and I am not getting an error, therefore I don't know if I am doing it right. I would assume when using the mailer that letter opener would work once the mailer is fired (should it all be working correctly), but I am not sure. I have posted all relevant code below. Thanks in advance!
.rake file
namespace :agent_cards do
desc 'Sends an email to an agent with a license expiring 2 months from today'
task license_expire_agent: :environment do
Rails.logger.info "Mailer Method #{ActionMailer::Base.delivery_method}"
AgentCard.all.each do |agent_card|
if agent_card.real_estate_license_expires_at == Date.today + 2.months
LicenseExpireMailer.license_expire_agent(#agent_card, #agent).deliver_later
end
end
end
end
namespace :agent_cards do
desc 'Sends an email to an the agent development manager when a license expires 1 week from today'
task license_expire_mgr: :environment do
Rails.logger.info "Mailer Method #{ActionMailer::Base.delivery_method}"
AgentCard.all.each do |agent_card|
if agent_card.real_estate_license_expires_at == Date.today + 7
LicenseExpireMailer.license_expire_mgr(#agent_card, #agent).deliver_later
end
end
end
end
license_expire_agent_mailer.rb
class LicenseExpireMailer < ActionMailer::Base
default from: "Mike <help#mike.com>"
def license_expire_agent(agent, agent_card)
#agent = agent
#agent_card = agent_card
mail to: "mike#mike.com", subject: 'Your license is about to expire!'
end
end
license_expire_mgr_mailer.rb
class LicenseExpireMailer < ActionMailer::Base
default from: "Mike <help#mike.com>"
def license_expire_mgr(agent, agent_card)
#agent = agent
#agent_card = agent_card
# Head of Agent Development
mail to: "mike#mike.com", subject: "#{#agent.name}'s License Expiring"
end
end
When I try to test the rake task I enter
rake agent_cards:license_expire_agent
or
rake agent_cards:license_expire_mgr
Error
NameError: uninitialized constant LicenseExpireMailer
/Users/michaelwiesenhart/Code/lib/tasks/license_expiration.rake:7:in `block (3 levels) in <top (required)>'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1#global/gems/activerecord- 4.2.6/lib/active_record/relation/delegation.rb:46:in `each'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1#global/gems/activerecord-4.2.6/lib/active_record/relation/delegation.rb:46:in `each'
/Users/michaelwiesenhart/Code/lib/tasks/license_expiration.rake:5:in `block (2 levels) in <top (required)>'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/task.rb:248:in `block in execute'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/task.rb:243:in `each'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/task.rb:243:in `execute'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/task.rb:187:in `block in invoke_with_call_chain'
/Users/michaelwiesenhart/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/monitor.rb:214:in `mon_synchronize'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/task.rb:180:in `invoke_with_call_chain'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/task.rb:173:in `invoke'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/application.rb:150:in `invoke_task'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/application.rb:106:in `block (2 levels) in top_level'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/application.rb:106:in `each'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/application.rb:106:in `block in top_level'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/application.rb:115:in `run_with_threads'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/application.rb:100:in `top_level'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/application.rb:78:in `block in run'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/application.rb:176:in `standard_exception_handling'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/lib/rake/application.rb:75:in `run'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/gems/rake-11.1.2/bin/rake:33:in `<top (required)>'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/bin/rake:23:in `load'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/bin/rake:23:in `<main>'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/bin/ruby_executable_hooks:15:in `eval'
/Users/michaelwiesenhart/.rvm/gems/ruby-2.3.1/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => agent_cards:license_expire_agent
Your mailer file name does not match with the mailer class name as per Rails convention.
Mailer class should be placed in this path:
app/mailers/license_expire_mailer.rb
When I run the specs of my Rails project, I usually use rake, which outputs the following:
josh#macbuech:~/Documents/Work/MuheimWebdesign/base/src (master *)$ rake
/Users/josh/.rvm/rubies/ruby-2.1.0/bin/ruby -I/Users/josh/.rvm/gems/ruby-2.1.0#base/gems/rspec-core-3.1.7/lib:/Users/josh/.rvm/gems/ruby-2.1.0#base/gems/rspec-support-3.1.2/lib /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/rspec-core-3.1.7/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb --color --format Fuubar
Run options: include {:focus=>true}
All examples were filtered out; ignoring {:focus=>true}
121/121 |======================= 100 ========================>| Time: 00:00:07
Pending:
File upload uses an uploaded file (from the temporary cache) after a re-display and then successful submit of the form
# Seems to be an issue of Carrierwave, see https://github.com/carrierwaveuploader/carrierwave/issues/1414
# ./spec/features/file_upload_spec.rb:41
Finished in 7.05 seconds (files took 5.82 seconds to load)
121 examples, 0 failures, 1 pending
Top 3 slowest examples (1.76 seconds, 25.0% of total time):
RegistrationsController POST 'create' valid input creates a guest user and converts it to a registered one
0.76552 seconds ./spec/controllers/registrations_controller_spec.rb:9
Signing out signs the user out
0.53429 seconds ./spec/features/user/sessions/destroy_spec.rb:9
File upload uses an uploaded file (from the temporary cache) after a re-display and then successful submit of the form
0.4628 seconds ./spec/features/file_upload_spec.rb:41
Top 3 slowest example groups:
Signing out
0.53429 seconds average (0.53429 seconds / 1 example) ./spec/features/user/sessions/destroy_spec.rb:3
RegistrationsController
0.41286 seconds average (0.82572 seconds / 2 examples) ./spec/controllers/registrations_controller_spec.rb:3
File upload
0.35467 seconds average (2.13 seconds / 6 examples) ./spec/features/file_upload_spec.rb:3
Randomized with seed 56456
0 failures.
But when I run it with the rspec command, I get this:
josh#macbuech:~/Documents/Work/MuheimWebdesign/base/src (master *)$ rspec
Run options: include {:focus=>true}
All examples were filtered out; ignoring {:focus=>true}
......................*.............................................../Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activerecord-4.2.0/lib/active_record/associations.rb:1693: warning: already initialized constant Role::HABTM_Users
/Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activerecord-4.2.0/lib/active_record/associations.rb:1693: warning: previous definition of HABTM_Users was here
/Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activerecord-4.2.0/lib/active_record/associations.rb:1693: warning: already initialized constant User::HABTM_Roles
/Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activerecord-4.2.0/lib/active_record/associations.rb:1693: warning: previous definition of HABTM_Roles was here
......FFFF.............F...........................
Pending:
File upload uses an uploaded file (from the temporary cache) after a re-display and then successful submit of the form
# Seems to be an issue of Carrierwave, see https://github.com/carrierwaveuploader/carrierwave/issues/1414
# ./spec/features/file_upload_spec.rb:41
Failures:
1) User creating a user validates uniqueness of name
Failure/Error: expect(#user).to have(1).error_on(:name)
expected 1 error on :name, got 2
# ./spec/models/user_spec.rb:90:in `block (3 levels) in <top (required)>'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `block in load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:240:in `load_dependency'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/spring-commands-rspec-1.0.4/lib/spring/commands/rspec.rb:18:in `call'
# -e:1:in `<main>'
2) User creating a user validates presence of email
Failure/Error: expect(#user).to have(1).error_on(:email)
expected 1 error on :email, got 2
# ./spec/models/user_spec.rb:95:in `block (3 levels) in <top (required)>'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `block in load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:240:in `load_dependency'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/spring-commands-rspec-1.0.4/lib/spring/commands/rspec.rb:18:in `call'
# -e:1:in `<main>'
3) User creating a user validates presence of password
Failure/Error: expect(#user).to have(1).error_on(:password)
expected 1 error on :password, got 2
# ./spec/models/user_spec.rb:100:in `block (3 levels) in <top (required)>'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `block in load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:240:in `load_dependency'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/spring-commands-rspec-1.0.4/lib/spring/commands/rspec.rb:18:in `call'
# -e:1:in `<main>'
4) User creating a user validates presence of name
Failure/Error: expect(#user).to have(1).error_on(:name)
expected 1 error on :name, got 2
# ./spec/models/user_spec.rb:83:in `block (3 levels) in <top (required)>'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `block in load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:240:in `load_dependency'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/spring-commands-rspec-1.0.4/lib/spring/commands/rspec.rb:18:in `call'
# -e:1:in `<main>'
5) User creating a guest validates presence of name
Failure/Error: expect(#guest).to have(1).error_on(:name)
expected 1 error on :name, got 2
# ./spec/models/user_spec.rb:43:in `block (3 levels) in <top (required)>'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `block in load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:240:in `load_dependency'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
# /Users/josh/.rvm/gems/ruby-2.1.0#base/gems/spring-commands-rspec-1.0.4/lib/spring/commands/rspec.rb:18:in `call'
# -e:1:in `<main>'
Finished in 7.34 seconds (files took 0.47745 seconds to load)
121 examples, 5 failures, 1 pending
Failed examples:
rspec ./spec/models/user_spec.rb:86 # User creating a user validates uniqueness of name
rspec ./spec/models/user_spec.rb:93 # User creating a user validates presence of email
rspec ./spec/models/user_spec.rb:98 # User creating a user validates presence of password
rspec ./spec/models/user_spec.rb:81 # User creating a user validates presence of name
rspec ./spec/models/user_spec.rb:40 # User creating a guest validates presence of name
Top 3 slowest examples (2.18 seconds, 29.7% of total time):
Signing up signs up a new user
1.07 seconds ./spec/features/user/registration/new_spec.rb:4
I18n offers contents in english
0.66078 seconds ./spec/features/i18n_spec.rb:10
File upload displays a preview of an uploaded file (from the temporary cache) after a re-display of the form
0.44416 seconds ./spec/features/file_upload_spec.rb:27
Top 3 slowest example groups:
Signing up
1.07 seconds average (1.07 seconds / 1 example) ./spec/features/user/registration/new_spec.rb:3
File upload
0.34402 seconds average (2.06 seconds / 6 examples) ./spec/features/file_upload_spec.rb:3
I18n
0.25478 seconds average (0.76435 seconds / 3 examples) ./spec/features/i18n_spec.rb:3
Randomized with seed 49596
1 warning and 5 failures, and the failures seem have to do with the warning (at least this is a possibility). It looks like some association is loaded twice, which results in the errors in the specs.
How can I debug this situation? Because there seem to be so many possibilities, it's hard to post more specific code snippets here. But here's the link to my GitHub repo, maybe someone can reproduce it?
https://github.com/jmuheim/base
I debug the app and found out:
1) Your specs depend on order. For example
bin/rspec spec --seed 49796 # gives 5 failures
bin/rspec spec --seed 1 # gives 0 failure
2) Also I place caller to User and I can see that model User is loaded twice (you should stop spring to see the first calling). Analyzing caller stack (for seed 49796) I noticed that second one is different and has strange lines
...
"/home/vaska/projects/base/spec/i18n_keys_spec.rb:84:in `block in project_models'",
"/home/vaska/projects/base/spec/i18n_keys_spec.rb:83:in `each'",
"/home/vaska/projects/base/spec/i18n_keys_spec.rb:83:in `project_models'",
"/home/vaska/projects/base/spec/i18n_keys_spec.rb:61:in `block (3 levels) in <top (required)>'",
"/home/vaska/projects/base/spec/i18n_keys_spec.rb:60:in `each'",
"/home/vaska/projects/base/spec/i18n_keys_spec.rb:60:in `block (2 levels) in <top (required)>'",
...
This line loads models second time. When I comment lines 86-88 in i18n_keys_spec all three cases passes successfully (I mean bin/rake, bin/rspec spec 1, bin/rspec spec --seed 49796).
I am not sure that removing these lines are solution because I suspect that spring caches the app and that is why it works now. Maybe you can check if class defined before require model file (for example spring itself checks it). From other hand i18n_keys_spec loads rails_helper which should load all app including models.
Hope it helps you
I'm trying to make rspec testcases. But, Rspec fails for Name has already been taken.
It seems "let" evalulated each time "product" called.
How can I fix it?
Console
./spec/models/spree/product_decorator_spec.rb:31:in `block (4 levels) in <top (required)>'
ActiveRecord::RecordInvalid: Validation failed: Name has already been taken
./spec/models/spree/product_decorator_spec.rb:6:in `block (3 levels) in <top (required)>'
./spec/models/spree/product_decorator_spec.rb:20:in `block (4 levels) in <top (required)>'
./spec/models/spree/product_decorator_spec.rb:23:in `block (4 levels) in <top (required)>'
ActiveRecord::RecordInvalid: Validation failed: Name has already been taken
./spec/models/spree/product_decorator_spec.rb:6:in `block (3 levels) in <top (required)>'
./spec/models/spree/product_decorator_spec.rb:12:in `block (4 levels) in <top (required)>'
./spec/models/spree/product_decorator_spec.rb:15:in `block (4 levels) in <top (required)>'
product_decorator_spec.rb
require 'spec_helper'
describe Spree::Product do
context '#create' do
let(:us) { create(:zone, name: "US") }
let(:china) { create(:zone, name: "China") }
let(:japan) { create(:zone, name: "Japan") }
context "when a product has no ng zone" do
let(:product) { create(:product, zones: [us, china, japan]) }
it "should get ng_zones correctly" do
product.ng_zones.should match_array []
end
end
context "when a product has one ng zone" do
let(:product) { create(:product, zones: [us, china]) }
it "should get ng_zones correctly" do
product.ng_zones.should match_array ["Japan"]
end
end
context "when a product has two ng zone" do
let(:product) { create(:product, zones: [us]) }
it "should get ng_zones correctly" do
product.ng_zones.should match_array ["China", "Japan"]
end
end
end
end
The body of the let is evaluated with every it block. I'm assuming you have a uniqueness constraint on your Zone classes.
You have 2 possibilities
Either build the variables in a before(:all) block and assign them to something like #us
Clean up your database after(:each)
You are testing the Product#create so, you won't need to really create zones for this particular test.
Instead you could just use build_stubbed method.
let(:us) { build_stubbed(:zone, name: "US") }
let(:china) { build_stubbed(:zone, name: "China") }
let(:japan) { build_stubbed(:zone, name: "Japan") }
This way, it's creation process are not going to rely on the database and also the validations for the Zone model and you have an awesome performance boost since you are not hitting the db for for each single test.
You can read about build_stubbed here.
Please let me know if it helps you somehow. ;)