URI ::InvalidURIError не приводит к прохождению теста

#ruby-on-rails #rspec #factory-bot

#ruby-on-rails #rspec #factory-бот

Вопрос:

Я пытаюсь заставить тест пройти, когда указан недопустимый URL:

 it "is invalid when URL format is NOT valid" do
  entity = FactoryGirl.build(:entity, url: 'blah blah')
  expect(entity).to have(1).errors_on(:url)
end
  

Но тест завершается неудачей:

 Failures:

1) Entity is invalid when url format is NOT valid
   Failure/Error: entity = FactoryGirl.build(:entity, url: 'blah blah')
   URI::InvalidURIError:
     bad URI(is not URI?): blah blah
  

Похоже, что ошибка не возникает таким образом, чтобы ее можно было распознать с помощью платформы тестирования. Чего я не понимаю?

app/models/entity.rb:

 require 'uri'
class Entity < ActiveRecord::Base

  validates :url, presence: true, uniqueness: true, :format => { :with => URI.regexp }

  ...

  def url=(_link)

    if _link
        uri = URI.parse(_link)

        if (!uri.scheme)
            link = "http://"   _link
        else
            link = _link
        end
      super(link)
    end

  end
end
  

спецификация/модели/entity_spec.rb:

 describe Entity do

  ...

  it "is invalid when url format is NOT valid" do
    entity = FactoryGirl.build(:entity, url: 'blah blah')
    expect(entity).to have(1).errors_on(:url)
  end

end
  

спецификация/фабрики/entity.rb:

 FactoryGirl.define do
  factory :entity do
    name { Faker::Company.name }
    url { Faker::Internet.url }
  end
end
  

Ответ №1:

Прошло некоторое время с тех пор, как я использовал Rspec, но я думаю, вы можете попробовать что-то вроде:

 expect {
  FactoryGirl.build(:entity, url: 'blah blah')
}.to raise_error(URI::InvalidURIError)
  

Объяснение вопроса в комментариях

Всякий раз, когда вы вызываете FactoryGirl.build(:entity, url: 'blah blah') библиотеку URI, возникает исключение (ваша ошибка). Исключение будет вызвано до того, как вы сможете назначить его entity переменной. Что приводит к сбою теста. expect Все они перехватят исключение и проверят, так ли это URI::InvalidURIError .

Комментарии:

1. Это сработало, но почему? Когда я попытался entity = FactoryGirl.build(:entity, url: 'blah blah') тогда expect(entity).to raise_error(URI::InvalidURIError) , я получаю ошибку, указанную в моем вопросе.

2. Привет @craig, рад, что это сработало 🙂 Всякий раз, когда вы вызываете FactoryGirl.build(:entity, url: 'blah blah') библиотеку URI, возникает исключение (ваша ошибка). Эта ошибка будет вызвана до того, как вы сможете присвоить ее entity переменной. Что приводит к сбою теста.

3. Хорошо, но у меня есть аналогичное требование к name свойству ( validates :name, presence: true, uniqueness: true ), которое перехватывается с использованием двухстрочного синтаксиса. В чем разница? Очевидно, это как-то связано с блоком в :url требовании.