Trying to use a Rspec shared example to test two URL-like properties:
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_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
Clearly I need to send a reference to the :url and :wikipedia_url attributes to the shared example, but how?
Your shared example block takes an argument method, but you do not pass one to it. However, you are very close. Just change:
context ':url attribute' do
it_behaves_like "a URL", :url
end
Now we are passing the :url symbol to the shared example as method. Then you need to change your references to :method= (which will fail because it is literally subject.method=) to subject.send("#{method}=", value) so that we are actually calling the method url=. e.g.
it "ensures that :#{method} does not exceed 255 characters" do
subject.send("#{method}=", 'http://' + '@' * 256)
expect(subject).to_not be_valid
end
All that being said I would recommend changing the name of the local variable from method to something else (maybe even method_name) just to avoid confusion of the method() method and your local variable method.
Full Example
You can "provide context to a shared group using a block", as described here.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With