Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Failing uniqueness validation with FactoryGirl

I'm having problems with FactoryGirl, I'm using sequence to avoid duplicating fields, but validations are failing anyway.

Output:

  1) CustomersController anonymous user GET #edit is redirected to signin when accessing edit form
     Failure/Error: get :edit, id: create(:customer)
     ActiveRecord::RecordInvalid:
       Validation failed: Email has already been taken, Email has already been taken
     # ./spec/controllers/customers_controller_spec.rb:25:in `block (4 levels) in <top (required)>'
     # -e:1:in `<main>'

  3) Customer public class methods executes its methods correctly #find_by_id_or_name finds customer by name
     Failure/Error: let(:john) {create(:customer, name: 'John Doe X')}
     ActiveRecord::RecordInvalid:
       Validation failed: Email has already been taken, Email has already been taken
     # ./spec/models/customer_spec.rb:25:in `block (3 levels) in <top (required)>'
     # ./spec/models/customer_spec.rb:38:in `block (5 levels) in <top (required)>'
     # -e:1:in `<main>'

Factories:

FactoryGirl.define do
  factory :customer do
    user
    name {Faker::Name.name}
    sequence(:mail) { |n| "person#{n}@example.com" }
    address {Faker::Address.street_address}
    phone {Faker::PhoneNumber.phone_number}
  end
end

FactoryGirl.define do
  factory :user do
    sequence(:email) {|i| "example#{i}@example.com"}
    password {Faker::Internet.password(10)}
  end
end

These are the tests that are failing:

RSpec.describe Customer, type: :model do
    describe "public class methods" do
        let(:john) {create(:customer, name: 'John Doe X')}
        let(:frank) {create(:customer)}


    context "responds to its methods" do
      it "responds to #find_by_id_or_name" do
        expect(Customer).to respond_to(:find_by_id_or_name)
      end
    end

    context "executes its methods correctly" do
      context "#find_by_id_or_name" do
        it "finds customer by name" do
          customer = Customer.find_by_id_or_name('John Doe X')
          expect(customer).to eq john
        end
        it "finds customer by id" do
          customer = Customer.find_by_id_or_name(frank.id)
          expect(customer).to eq frank
        end
      end
    end
  end
end



RSpec.describe CustomersController, type: :controller do
  context "signed in user" do
    before :each do
      @user = create(:user)
    end
    describe "GET #edit" do
      it "renders :edit view" do
        get :edit, id: create(:customer).id
        expect(response).to render_template(:edit)
      end
    end

    describe "DELETE #destroy" do
      before :each do
        @customer = create(:customer, user: @user)
      end
      it "deletes record" do
        expect {delete :destroy, id: @customer.id}.to change(Customer, :count).by(-1)
      end
    end
  end
end

This is happening to me all over my app. I just copied some tests that apply to Customer.

Thanks

like image 283
FranGoitia Avatar asked Nov 09 '22 10:11

FranGoitia


1 Answers

My problem was related to not appropiately configuring database_cleaner. The configuration in this post solves the problem: How can I clean my database between erroneous rspec specs?

like image 150
FranGoitia Avatar answered Nov 15 '22 04:11

FranGoitia