我正在测试从头开始构建用户身份验证。
我从测试和设置验证开始,他们都通过了。一旦我添加了format: { with: ... }
方法,我的测试套件就崩溃了。
以下是代码的失败:
Failures:
1) User validations requires an email
Failure/Error: expect(user).to validate_presence_of(:email)
NoMethodError:
undefined method `validate_presence_of' for #<RSpec::ExampleGroups::User::Validations:0x007fae7f5551b0>
# ./spec/models/user_spec.rb:14:in `block (3 levels) in <top (required)>'
2) User validations requires a unique email
Failure/Error: expect(user).to validate_uniqueness_of(:email)
NoMethodError:
undefined method `validate_uniqueness_of' for #<RSpec::ExampleGroups::User::Validations:0x007fae83193b90>
# ./spec/models/user_spec.rb:18:in `block (3 levels) in <top (required)>'
3) User validations requires a unique email (case insensitive)
Failure/Error: expect(user).to validate_uniqueness_of(:email)
NoMethodError:
undefined method `validate_uniqueness_of' for #<RSpec::ExampleGroups::User::Validations:0x007fae83168670>
# ./spec/models/user_spec.rb:23:in `block (3 levels) in <top (required)>'
Finished in 0.04888 seconds (files took 1.2 seconds to load)
6 examples, 3 failures
规格/模型/ user_spec.rb
require 'rails_helper'
RSpec.describe User, :type => :model do
let(:valid_attr) { attributes_for(:user) }
context "validations" do
let(:user) { User.new(valid_attr) }
before do
User.create(valid_attr)
end
it "requires an email" do
expect(user).to validate_presence_of(:email)
end
it "requires a unique email" do
expect(user).to validate_uniqueness_of(:email)
end
it "requires a unique email (case insensitive)" do
user.email = "BROWN@DOGS.COM"
expect(user).to validate_uniqueness_of(:email)
end
it "requires the email to look like an email" do
user.email = "brown"
expect(user).to_not be_valid
end
end
describe "#downcase_email" do
it "makes the email attribute lowercase" do
user = User.new(valid_attr.merge(email: "YELLOW@DOGS.COM"))
expect{ user.downcase_email }.to change{ user.email }.
from("YELLOW@DOGS.COM").
to("yellow@dogs.com")
end
it "downcases an email before saving" do
user = build(:user)
user.email = "BROWN@DOGS.COM"
expect(user.save).to be true
expect(user.email).to eq("brown@dogs.com")
end
end
end
工厂女孩 users.rb
FactoryGirl.define do
factory :user do
first_name "Charlie"
last_name "Brown"
email "brown@dogs.com"
password "charbar1234"
password_confirmation "charbar1234"
end
end
模型/ user.rb
class User < ActiveRecord::Base
has_secure_password
validates :email, presence: true,
uniqueness: true,
format: {
with: /\A[A-Za-z0-9._%+-]+@[A-Za-z0-9\.-]+\.[A-Za-z]+\Z/
}
before_save :downcase_email
def downcase_email
self.email = email.downcase
end
end
答案 0 :(得分:1)
Rspec可能会被这个额外的格式参数搞糊涂,因此无法正确动态创建validates_*_of
方法。您可以将测试重写为更直接:
it "requires an email" do
expect(user).to be_valid
# other test on error message here perhaps?
end
或将格式部分放在自己的验证行上:
validates :email, presence: true, uniqueness: true
validates :email, format: {
with: /\A[A-Za-z0-9._%+-]+@[A-Za-z0-9\.-]+\.[A-Za-z]+\Z/
}
答案 1 :(得分:1)
更好的方法是使用URI对象:
validates_format_of :website_url, with: URI.regexp