Chimed Palden
Chimed Palden

Reputation: 135

Rspec : “Email has already been taken"

I was writing test for registeration form and i got error "Email has already been taken" I have googled this problem and come up this gem

gem 'database_cleaner', git: 'https://github.com/DatabaseCleaner/database_cleaner.git'

But it still didn't fixed the bug I may messed up with the database_cleaner setup

spec_helper.rb

require 'database_cleaner'
Dir["./spec/support/**/*.rb"].sort.each { |f| require f}
RSpec.configure do |config|
  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
    expectations.syntax = :should
  end


  config.mock_with :rspec do |mocks|

    mocks.verify_partial_doubles = true
  end

  config.before(:suite) do
    DatabaseCleaner[:active_record].strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

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

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

rails_helper.rb

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'capybara/rspec'

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  config.use_transactional_fixtures = true
  config.infer_spec_type_from_file_location!
  config.filter_rails_from_backtrace!
end

factories.rb

FactoryGirl.define do
    factory :identity do |f|
        f.name Faker::Name.name
        f.email Faker::Internet.email
        f.password Faker::Internet.password(4,40)
    end
end

identity_spec.rb

it "Registration successfully" do
        user = FactoryGirl.create(:identity)
        visit(new_identity_path)
        fill_in('Name', :with => user.name)
        fill_in('Email', :with => user.email)
        fill_in('Password', :with => user.password)
        fill_in('Password confirmation', :with => user.password)
        click_button 'Register'
        page.should have_content("You'r successfully logged in")
    end

UPDATE:

it "Invalid password" do
    user = FactoryGirl.create(:identity)
    puts "USER Email: #{user.email}"
    visit('/login')
    fill_in('Email', :with => user.email)
    fill_in('Password', :with => "incorrect")
    click_button 'Login'
    page.should have_content("Invalid info")
end

it "Registration successfully" do
    puts "IDENTITY COUNT: #{Identity.count}"
    user = FactoryGirl.create(:identity)
    puts "USER Email: #{user.email}"
    # visit(new_identity_path)
    # fill_in('Name', :with => user.name)
    # fill_in('Email', :with => user.email)
    # fill_in('Password', :with => user.password)
    # fill_in('Password confirmation', :with => user.password)
    # click_button 'Register'
    # page.should have_content("You'r successfully logged in")
end

Output

USER Email: [email protected]
.IDENTITY COUNT: 0
USER Email: [email protected]
.

.

Upvotes: 1

Views: 893

Answers (2)

zetetic
zetetic

Reputation: 47548

Capybara tests should not use transactions. Turn off transactions in rails_helper.rb with:

config.use_transactional_fixtures = false

The database_cleaner docs explain why:

You'll typically discover a feature spec is incorrectly using transaction instead of truncation strategy when the data created in the spec is not visible in the app-under-test.

A frequently occurring example of this is when, after creating a user in a spec, the spec mysteriously fails to login with the user. This happens because the user is created inside of an uncommitted transaction on one database connection, while the login attempt is made using a separate database connection. This separate database connection cannot access the uncommitted user data created over the first database connection due to transaction isolation.

Upvotes: 0

jeffdill2
jeffdill2

Reputation: 4114

Looks like you might have it slightly misconfigured.

Try putting require 'database_cleaner' in your spec_helper.rb file.

And then include require 'spec_helper' in your rails_helper.rb file.

If that doesn't fix it, then please include the rest of your spec_helper.rb and rails_helper.rb files in your question.


UPDATE

As far as I can tell, everything looks good in your helper files. The only difference I see between your implementation and my own is that you've got the strategy defined with:

DatabaseCleaner[:active_record].strategy = :transaction

whereas mine is simply:

DatabaseCleaner.strategy = :transaction

I don't think that would be the issue but it's worth a shot.

If that doesn't fix it, can you throw a couple of puts statements in your spec tests and let us know the output? Like so:

puts "IDENTITY COUNT: #{Identity.count}"
user = FactoryGirl.create(:identity)
puts "USER EMAIL: #{user.email}"

This will let us know two things:

  1. is database_cleaner actually not working (count should be 0 if it is working)
  2. is Faker using the same exact email address every time it's used.

Upvotes: 2

Related Questions