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?
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