使用 Rspec 共享示例来测试 Ruby class' 属性
Use Rspec shared examples to test a Ruby class' attributes
尝试使用 Rspec 共享示例来测试两个 URL 类属性:
spec/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
spec/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
属性的引用发送到共享示例,但是如何?
您可以"provide context to a shared group using a block",如所述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
您的共享示例块接受一个参数 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
.
尝试使用 Rspec 共享示例来测试两个 URL 类属性:
spec/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
spec/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
属性的引用发送到共享示例,但是如何?
您可以"provide context to a shared group using a block",如所述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
您的共享示例块接受一个参数 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
.