3
votes

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, :password  => 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

4

4 Answers

1
votes

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.

1
votes

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.

0
votes

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.

0
votes

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