Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this Rspec test returning "email already taken"

This is my spec file, when adding test for context "not as singable updates user balance" I get the error below.

require 'spec_helper'

describe Sale do 

  context 'after_commit' do

    context 'assignable' do 
      sale = FactoryGirl.create(:sale, earned_cents: 10, assignable: true)
      after { sale.run_callbacks(:commit) }

      it 'updates user balance' do
        sale.user.balance.should == sale.earned
      end
    end

    context 'not assignable' do 
      sale = FactoryGirl.create(:sale, earned_cents: 10, assignable: false)
      after { sale.run_callbacks(:commit) }

      it 'does not updates user balance' do
        sale.user.balance.should_not == sale.earned
      end
    end

  end 
end

And the factories

require 'faker'

FactoryGirl.define do
  factory :user do
    email Faker::Internet.email
    password "mypassword"
  end

FactoryGirl.define do
  factory :sale do
    earned_cents 5
    user
  end
end

On /spec/spec_helper.rb I also had this

require 'database_cleaner'
RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end

And this is the error I'm getting.

`save!': Validation failed: Email has already been taken (ActiveRecord::RecordInvalid)

I guess its related to the user reference inside Sale Factory, but I have no idea why it is not generating a new user for the second test or deleting it from the database. Any idea?

like image 633
Martin Avatar asked Dec 06 '22 04:12

Martin


1 Answers

In your User factory, try this instead:

factory :user do
  email { Faker::Internet.email }
  password "mypassword"
end

Why you Must Enclose In Curly Brackets: to Avoid Caching Values

The factory(:user) block is run when defining the factory, and not every time a record is created. So if Factory::Internet.email evaluated to [email protected] the first time, then the factory would attempt to create all subsequent users with that very same email!) (as per @kristinalim, Edited for grammar)

like image 74
GladstoneKeep Avatar answered Dec 14 '22 23:12

GladstoneKeep