Используйте общие примеры Rspec для тестирования атрибутов класса Ruby - PullRequest
0 голосов
/ 01 мая 2018

Попытка использовать общий пример Rspec для проверки двух URL-подобных свойств:

спецификация / entity_spec.rb

require 'entity'
require 'shared_examples/a_url'

describe Entity do

  # create valid subject
  subject { described_class.new(name: 'foobar') }

  context ':url attribute' do
    it_behaves_like "a URL"
  end

  context ':wikipedia_url attribute' do
    it_behaves_like "a URL"
  end

end

спецификация / shared_examples / a_url.rb

shared_examples_for('a URL') do |method|

    it "ensures that :#{method} does not exceed 255 characters" do
      subject.send(:method=, 'http://' + '@' * 256)
      expect(subject).to_not be_valid
    end

    it "ensures that :#{method} do not accept other schemes" do
      subject.send(:method=, 'ftp://foobar.com')
      expect(subject).to_not be_valid
    end

    it "ensures that :#{method} accepts http://" do
      subject.send(:method=, 'http://foobar.com')
      expect(subject).to be_valid
    end

    it "ensures that :#{method} accepts https://" do
      subject.send(:method=, 'https://foobar.com')
      expect(subject).to be_valid
    end

end

Ясно, что мне нужно отправить ссылку на атрибуты :url и :wikipedia_url на общий пример, но как?

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Ваш общий пример блока принимает аргумент method, но вы не передаете его ему. Тем не менее, вы очень близки. Просто измените:

context ':url attribute' do
  it_behaves_like "a URL", :url
end

Теперь мы передаем символ :url общему примеру как method. Затем вам нужно изменить ссылки на :method= (что не удастся, потому что буквально subject.method=) на subject.send("#{method}=", value), чтобы мы фактически вызывали метод url=. например,

it "ensures that :#{method} does not exceed 255 characters" do
  subject.send("#{method}=", 'http://' + '@' * 256)
  expect(subject).to_not be_valid
end

При этом я бы порекомендовал изменить имя локальной переменной с method на другое (возможно, даже method_name), чтобы избежать путаницы method() с вашей локальной переменной method.

Полный пример

0 голосов
/ 01 мая 2018

Вы можете «предоставить контекст совместно используемой группе, используя блок», как описано здесь .

require "set"

RSpec.shared_examples "a collection object" do
  describe "<<" do
    it "adds objects to the end of the collection" do
      collection << 1
      collection << 2
      expect(collection.to_a).to match_array([1, 2])
    end
  end
end

RSpec.describe Array do
  it_behaves_like "a collection object" do
    let(:collection) { Array.new }
  end
end

RSpec.describe Set do
  it_behaves_like "a collection object" do
    let(:collection) { Set.new }
  end
end
...