RSpec与网站格式验证失败

时间:2016-04-12 07:11:21

标签: ruby-on-rails validation rspec factory-bot shoulda

我使用的是rails4,factory_ girl,rspec和shoulda matchers。如果我使用下面的代码运行rspec,我会收到此错误:

Product should validate that :website cannot be empty/falsy, producing a custom validation error on failure
 Failure/Error: self.website = "http://#{self.website}" unless self.website[/^https?/]

 NoMethodError:
   undefined method `[]' for nil:NilClass

如果我从unless self.website[/^https?/]方法中删除format_website,我会收到此错误:

Product did not properly validate that :website cannot be empty/falsy,
   producing a custom validation error on failure.
     After setting :website to ‹nil› -- which was read back as ‹"http://"›
     -- the matcher expected the Product to be invalid and to produce a
     validation error matching ‹/can't be blank/› on :website. The record
     was indeed invalid, but it produced these validation errors instead:

     * user: ["can't be blank"]
     * name: ["can't be blank"]
     * company: ["can't be blank"]

我该怎么做才能使这项工作?

产品型号

belongs_to :user

validates :name, presence: { message: "can't be blank" }, length: { maximum: 140, message: "can't be longer than 140 characters" }, uniqueness: { message: "already exists" }
validates :company, presence: { message: "can't be blank" }, length: { maximum: 140, message: "can't be longer than 140 characters" }
validates :website, presence: { message: "can't be blank" }, length: { maximum: 140, message: "can't be longer than 140 characters" }

before_validation :format_website
validate :website_validator


def format_website
  self.website = "http://#{self.website}" unless self.website[/^https?/]
end

def website_validator
  self.errors.add :website, "format is invalid!" unless website_valid?
end

def website_valid?
  !!website.match(/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-=\?]*)*\/?$/)
end

工厂

FactoryGirl.define do
  factory :product do
    name { Faker::Commerce.product_name }
    company { Faker::Company.name }
    website { 'https://example.com' }
    user
  end
end

it { is_expected.to callback(:format_website).before(:validation) } #this one is not important, if I take out it still gives the same error
it { is_expected.to validate_presence_of(:name).with_message(/can't be blank/) }
it { is_expected.to validate_presence_of(:company).with_message(/can't be blank/) }
it { is_expected.to validate_presence_of(:website).with_message(/can't be blank/) }
it { is_expected.to belong_to(:user) }

1 个答案:

答案 0 :(得分:2)

您应确保website不是nil

def format_website
  return if website.blank?

  self.website = "http://#{self.website}" unless self.website[/^https?/]
end

在这种情况下,如果self.website == nil,您将尝试在nil对象上调用方法[],因此是第一个错误。

对于第二种情况,答案在于您从rspec获得的回报:

  

将网站设置为后,将其作为<“http://”>

读回

您的方法format_website会返回"http://",这是因为网站为零。