使用Rspec共享示例来测试Ruby类'属性

时间:2018-05-01 13:27:41

标签: ruby rspec rspec3

尝试使用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 :(得分: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}}。

Full Example

答案 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