如何在实现和规范描述之间共享数据?

时间:2011-12-03 19:14:18

标签: ruby rspec rspec2

我想知道是否有任何良好的方法可以在规范的实现和描述之间重用数据......更具体地说,我希望能够执行以下操作:

describe "#some_method" do
  let(:arg1) { "Sample String 1" }
  let(:arg2) { "Sample String 2" }

  context "with '#{arg1}', its result" do
    specify { some_method(arg1).should == 1 }
  end

  context "with '#{arg2}', its result" do
    specify { some_method(arg2).should == 2 }
  end
end

当然,这段代码不起作用 - 在规范体外不能访问arg1和arg2。 是否有可能在不使用全局变量或外部类的情况下实现类似的结果?

更新

我对规范的输出感兴趣。像这样:

#some_method
  with 'Sample String 1' its result
    should == 1
  with 'Sample String 2' its result
    should == 2

3 个答案:

答案 0 :(得分:2)

答案是您不使用动态描述。 RSpec的方法是

describe "#some_method" do
  it "extracts the number correctly" do
    some_method("Sample String 1").should == 1
    some_method("Sample String 2").should == 2
  end
end

在您的规范中硬编码测试数据是没有问题的。如果您想要更完整的输出,可以使用custom matcher

require 'rspec'

class Test
  def some_method(str)
    str[/[0-9]+/].to_i
  end
end

RSpec::Matchers.define :return_value_for_argument do |result, arg|
  match do |actual|
    actual.call(arg) == result
  end

  description do
    "return #{result.inspect} for argument #{arg.inspect}"
  end
end

describe Test do
  let(:test) { Test.new }
  describe "#some_method" do
    subject { test.method(:some_method) }

    it { should return_value_for_argument 1, "str 1" }
  end
end

答案 1 :(得分:1)

在进行API测试时,我发现能够查看每个测试的路径,参数和响应非常有用。我已经使用the very useful tips given by Jeff Nyman将事物存储在每个测试的example.metatadata [:thing_i_want_to_store_like_url]中,并使用自定义格式化程序将其打印出来。

所以我的测试输出看起来像这样:

 that jonathan does not know it exists
 :path  : /user/20
 :params: {}
  => response: {"error"=>{"message"=>"error", "code"=>404}}

    that jonathan cannot edit
    :path  : /user/20/update
    :params: {:name=>"evil_name"}
    => response: {"error"=>{"message"=>"error", "code"=>404}}

答案 2 :(得分:0)

在您的描述中引用特定参数是不合适的。您的描述应该提供所需行为的人类可读描述,在大多数情况下不参考特定参数。