Validation problem with Autotest and Factory Girl
i have a problem with Autotest. In my user model are the username & email address unique. When i start Autotest everything works fine. In the secound round, from autotest, i have a
Validation failed: Email has already been taken, Username has already been taken
error in only two test. I dont understand why, i use factorygirl with an sequenze and this should generate everytime a new username.
This is my rspec2 file:
describe User do
specify { Factory.build(:user).should be_valid }
context "unique values" do
before :all do
@user = Factory.create(:user)
end
it "should have an unique email address" do
Factory.build(:user, :email => @user.email).should_not be_valid
end
it "should have an unique username" do
Factory.build(:user, :username => @user.username).should_not be_valid
end
end
context "required attributes" do
it "should be invalid without an email address" do
Factory.build(:user, :email => nil).should_not be_valid
end
it "should be invalid without an username" do
Factory.build(:user, :username => nil).should_not be_valid
end
it "should be invalid without an password" do
Factory.build(:user, :pas开发者_如何学编程sword => nil).should_not be_valid
end
it "should be invalid without an address" do
Factory.build(:user, :address => nil).should_not be_valid
end
end
end
The Factory:
Factory.sequence :username do |n|
"Outfit#{n}er"
end
Factory.sequence :email do |n|
"user#{n}@example.com"
end
Factory.define :user do |u|
u.username { Factory.next :username }
u.email { Factory.next :email }
u.password 'secret'
u.phone_number '02214565854'
u.association :address, :factory => :address
end
Factory.define :confirmed_user, :parent => :user do |u|
u.after_build { |user| user.confirm! }
end
The only two test that are not working are in the "unique values" context. All other test works without an error.
Thanks
This is exactly the problem I had just run into -- and had a strange experience where this problem didn't seem to happen if I was just running "rake spec".
After not finding an obvious answer, I did try something that seems to have solved the problem! It seems like setting a class variable inside a before() block is the culprit, if you're using FactoryGirl.
I had something very similar:
factory :widget do
sequence(:name) { |n| "widget#{n}" }
end
then:
describe Widget do
before(:each) { @widget = FactoryGirl.create(:widget) }
it ...yadda yadda...
@widget.foo()
end
end
autotest would find uniqueness constraint problems. I changed the rspect test to this:
describe Widget do
let(:widget) { FactoryGirl.create(:widget) }
it ...yadda yadda...
widget.foo()
end
end
...and the uniqueness constraint issues went away. Not sure why this happens, and it seems like it shouldn't happen, but may be a workable resolution.
I have gotten that problem from having the database not being properly cleared after some tests.
If you run: rake db:test:prepare before the autotest, does it still happen?
I eventually got around it by isolating which tests were not being cleared and fixing them (or removing them). Sorry, I can't remember what was the problem, but it had some error causing it.
Oh, and I ran it without spork, so that I could see my logger messages mixed in with the results.
Hope this helps.
The problem is probably in your config file. You have a line in your spec config file (probably spec_helper.rb) that reads:
config.use_transactional_fixtures = false
This should be:
config.use_transactional_fixtures = true
Or if you don't want to use transactional fixtures, you should have a before(:each) function in your test:
before :each do User.destroy_all end
Alternatively, I use the Sham gem for my factories because it's more compatible with non-transactional fixtures and sequences.
I ran into a very similar problem and I tried several of the suggestions on this thread with no luck. I did however fix it with adding the following to my spec_helper.rb:
# Clean up the database
require 'database_cleaner'
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.orm = "mongoid"
end
config.before(:each) do
DatabaseCleaner.clean
end
Also don't forget to add the DatabaseCleaner gem to your gemfile
精彩评论