0
votes

I have a model called "availabilities" in my Rails application that allows vendors to set their availability (i.e. their work hours). Thus, availabilities belong_to vendors and belong_to users, and a user has_many vendors and a vendor has_many availabilities.

I've been trying to create Rspec tests for my availability#destroy action. The specific test I refer to is:

#spec/controllers/availabilities_controller_spec.rb
require 'rails_helper'

RSpec.describe AvailabilitiesController, type: :controller do

  describe "availabilities#destroy action" do

    it "should allow a user who created the availability to destroy it"
      availability = FactoryBot.create(:availability) 
      sign_in availability.user
      delete :destroy, params: { id: availability.id, vendor_id: availability.vendor_id}
      availability = Availability.find_by_id(availability.id)
      expect(availability).to eq nil
   end 
  end
end

When I run this test however, I receive the following error:

"An error occurred while loading ./spec/controllers/availabilities_controller_spec.rb. Failure/Error: user = FactoryBot.create(:user)

ActiveRecord::RecordInvalid: Validation failed: Email has already been taken"

However, I use factory bot for my factories, and I have my user factory to run as a sequence (see below):

FactoryBot.define do
  factory :user do
    sequence :email do |n|
      "dummyEmail#{n}@gmail.com"
    end
    password "secretPassword"
    password_confirmation "secretPassword"
    confirmed_at Time.now
  end
end

How can the email already be taken? What could explain this error?

1
Could you please, show your models ?Gabriel Lidenor
What @Pavling said might be the case, but maybe you can do a binding.pry before the creation code and do an Avalability.all just to check. If it is the database not getting cleared out, the gem I use to clear the database out is database_cleaner.Daryll Santos

1 Answers

1
votes

I recommend you to use Faker along with FactoryBot. It will give your more flexibility and eliminate the need to do this sequence trick. Faker generates fake data with ease.

In any way, use database_cleaner to clean your test environment database after each test. You'll only need to set this is up:

# ./spec/rails_helper.rb

# start by truncating all the tables but then use the faster transaction strategy the rest of the time.
config.before(:suite) do
  DatabaseCleaner.clean_with(:truncation)
  DatabaseCleaner.strategy = :transaction
end

# start the transaction strategy as examples are run
config.around(:each) do |example|
  DatabaseCleaner.cleaning do
    example.run
  end
end