I am trying rspec and shoulda matchers as my new testing framework and I'm a little confused as to how to get the should validate_uniqueness_of(:attribute)
test to pass. Here is my simple model:
class Employee < ActiveRecord::Base
validates :name, presence: true
validates :title, presence: true
validates :department, presence: true
validates :avatar, presence: true
validates :email, presence: true, uniqueness: true
validates :reports_to, presence: true
mount_uploader :avatar, EmployeeAvatarUploader, on: :file_name
end
And here is the initial test:
RSpec.describe Employee, type: :model do
it { should validate_presence_of(:name) }
it { should validate_presence_of(:title) }
it { should validate_presence_of(:department) }
it { should validate_presence_of(:avatar) }
it { should validate_presence_of(:email) }
it { should validate_uniqueness_of(:email) }
it { should validate_presence_of(:reports_to) }
end
This fails with a description of the error pasted below:
`1) Employee should validate uniqueness of email
Failure/Error: should validate_uniqueness_of(:email)
Shoulda::Matchers::ActiveRecord::ValidateUniquenessOfMatcher::ExistingRecordInvalid:
validate_uniqueness_of works by matching a new record against an
existing record. If there is no existing record, it will create one
using the record you provide.
While doing this, the following error was raised:
PG::NotNullViolation: ERROR: null value in column "title" violates not-null constraint
DETAIL: Failing row contains (21, null, null, null, null, null, null, 2017-06-27 01:07:49.125445, 2017-06-27 01:07:49.125445, null, null).
: INSERT INTO "employees" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"
The best way to fix this is to provide the matcher with a record where
any required attributes are filled in with valid values beforehand.`
So my impression from the documentation was that my test should work as is. From the shoulda matcher documentation, I've tried this version of my test:
RSpec.describe Employee, type: :model do
it { should validate_presence_of(:name) }
it { should validate_presence_of(:title) }
it { should validate_presence_of(:department) }
it { should validate_presence_of(:avatar) }
it { should validate_presence_of(:email) }
it 'should validate uniqueness of email' do
email1 = FactoryGirl.create(:account, email: '[email protected]')
email2 = FactoryGirl.build(:account, email: '[email protected]' )
should validate_uniqueness_of(:email)
end
it { should validate_presence_of(:reports_to) }
end
This didn't seem to work either. Then I tried a variation of this test found by clicking Rspec validates_uniqueness_ofthis link
But still no luck. Could someone please direct me to the proper way of making this validation work?
You should be able to call it this way:
describe "validations" do
subject { Employee.new(title: "Here is the content") }
it { should validate_uniqueness_of(:email) }
end
Or with FactoryGirl
:
describe "validations" do
subject { FactoryGirl.build(:employee) }
it { should validate_uniqueness_of(:email) }
end
Your employees
table has a database level constraint requiring title
, so you need to create a valid employee
object first.
It looks as though in your second example you're building a account
instead of employee
.
See docs here: docs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With