2016-04-12 4 views
1

Я использую rails4, factory_ girl, rspec и shoulda matchers. Если я бегу RSpec с кодом ниже, я получаю эту ошибку: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) } 

ответ

2

Вы должны убедиться, что website не nil.

def format_website 
    return if website.blank? 

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

В том случае, если self.website == nil, вы будете пытаться вызвать метод [] на нулевой объект, следовательно, первой ошибки.

Во втором случае, ответ в ответ вы имеете от RSpec:

After setting :website to ‹nil› -- which was read back as ‹"http://"›

Ваш метод возвращает format_website"http://", что из-за веб-сайт является нулевым.

+0

born4new, я не задал должным образом этот вопрос. Я хотел бы знать, как я могу решить эту проблему, чтобы заставить валидатор работать. Должен ли я использовать другую проверку? –

+0

Снова, трудно сказать, не вызывая спецификации, которые вызывают проблему, но я уверен, что при создании вашей модели с FactoryGirl вы не создаете атрибут 'website'. Так сделайте это, и это должно исправить это. – born4new

+0

born4new, я обновил свой вопрос с завода. –