我正在尝试使用rspec和shoulda matchers作为我的新测试框架,我对如何通过should validate_uniqueness_of(:attribute)
测试感到有些困惑。这是我的简单模型:
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
这是初步测试:
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
此操作失败并显示下面粘贴的错误说明:
`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.`
所以我对文档的印象是我的测试应该按原样运行。从shoulda matcher文档中,我已经尝试过这个版本的测试:
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@blackducksoftware.com')
email2 = FactoryGirl.build(:account, email: 'email@blackducksoftware.com' )
should validate_uniqueness_of(:email)
end
it { should validate_presence_of(:reports_to) }
end
这似乎也没有用。然后,我点击Rspec validates_uniqueness_of此链接
尝试了此测试的变体但仍然没有运气。有人可以指导我进行这种验证的正确方法吗?
答案 0 :(得分:1)
你应该能够这样称呼它:
describe "validations" do
subject { Employee.new(title: "Here is the content") }
it { should validate_uniqueness_of(:email) }
end
或FactoryGirl
:
describe "validations" do
subject { FactoryGirl.build(:employee) }
it { should validate_uniqueness_of(:email) }
end
您的employees
表的数据库级别约束需要title
,因此您需要先创建一个有效的employee
对象。
在您的第二个示例中,您似乎正在构建account
而不是employee
。
请参阅此处的文档:docs
答案 1 :(得分:0)
describe Employee, type: :model do
context 'validations' do
it { should validate_uniqueness_of(:email) }
end
end
在这里,主体是隐含的。构建了Employee
的新实例(未创建)并验证了验证。