尝试使用Rspec共享示例来测试两个类似URL的属性:
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
显然,我需要向共享示例发送:url
和:wikipedia_url
属性的引用,但是如何?
答案 0 :(得分:2)
您的共享示例块接受参数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
。 e.g。
method
所有这一切我建议将局部变量的名称从method_name
更改为其他内容(甚至可能是method()
),以避免混淆method
方法和本地方法变量{{1}}。
答案 1 :(得分:1)
您可以“使用块为共享组提供上下文”,如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