加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 使用不同的参数重复RSpec示例组

发布时间:2020-12-17 03:14:25 所属栏目:百科 来源:网络整理
导读:我正在尝试保持我的规格清洁和干燥,但我对API的测试除了正在测试的API的版本之外是相同的.我可以简单地使用这样的东西重复规范: %w( v1 v2 ).each do |version| describe "Query #{version} API" do it "responds with JSON" # make the call using the ver
我正在尝试保持我的规格清洁和干燥,但我对API的测试除了正在测试的API的版本之外是相同的.我可以简单地使用这样的东西重复规范:

%w( v1 v2 ).each do |version|
  describe "Query #{version} API" do
    it "responds with JSON"
      # make the call using the version 
    end
  end
end

但我想要一些更清洁的东西,所以我写了这个方法:

module RepetitivelyDescribe
  def repetitively_describe(*args,&example_group_block)
    options = args.extract_options!
    options.delete(:for).each do |item|
      item_args = args.collect(&:dup) + [options.dup]
      item_args[0] << " [#{item}]"

      describe(*item_args) do
        example_group_block.call item
      end
    end
  end
end

RSpec::Core::ExampleGroup.extend RepetitivelyDescribe

然后我的测试看起来更像这样:

repetitively_describe "Query API",:for => %( v1 v2 ) do |version|
  it "responds with JSON"
    # make the call using the version 
  end
end

我意识到这有点迂腐,但它的压痕程度要低一些,如果我要打这么多话,我想让它变得更干净.

但是,当然,它并不像我想的那样工作.在我的repetitively_describe中描述的调用没有记录到RSpec输出(当使用文档格式输出时),虽然内部的示例会重复并按预期使用版本块参数.本质上,该上下文级别丢失(重复描述块的外部和内部的描述块被保留).

如果需要,在a gist中有更详细的示例代码.关于为什么这不太正常的任何线索?

解决方法

所以(道歉,如果我重复你已经知道的东西),但每次调用describe / context时,rspec都会创建一个新类,它是当前示例组类的子类(最终是RSpec :: Core :: ExampleGroup的子类)然后使用module_eval来评估该类上下文中的块.如果我跑

describe "foo" do
  puts "#{self}; #{self.superclass}"
  describe "behaviour 1" do
    puts "#{self}; #{self.superclass}"
    context "with x" do
      puts "#{self}; #{self.superclass}"
    end
  end
end

那么输出就是

#<Class:0x007fb772bfbc70>; RSpec::Core::ExampleGroup
#<Class:0x007fb772bfb180>; #<Class:0x007fb772bfbc70>
#<Class:0x007fb772bfa5f0>; #<Class:0x007fb772bfb180>

当你调用它时,rspec创建一个Example对象并将它附加到self上的类实例变量(当前示例组). rspec还会在示例的元数据中粘贴当前示例组,向上走这个示例组树就可以获得示例的完整描述.

您的重复描述方法调用描述,因此,当您调用example_group_block.call项时,self确实是新创建的示例组.当proc被评估时,它当然会记住self被调用时的值是什么,因此你对它的调用是在重复_decribe时最新的示例组(通过调用一些调用来检查自我的值,可以轻松验证)你的代码).类似地,对describe的调用将示例组添加为外部示例组的子项,而不是由repetitively_describe创建的子项.

你当然需要做的是调用example_group_block来保留self的正确值.

module RepetitivelyDescribe
  def repetitively_describe(*args,&example_group_block)
    options = args.extract_options!
    options.delete(:for).each do |item|
      item_args = args.collect(&:dup) + [options.dup]
      item_args[0] << " [#{item}]"

      describe(*item_args) do
        class_exec(item,&example_group_block)
      end
    end
  end
end

随着这种变化

describe('foo') do
  repetitively_describe "Query API",:for => %w( v1 v2 ) do |version|
    it "responds with JSON"
  end
end.descendant_filtered_examples.collect(&:full_description)

输出[“foo查询API [v1]用JSON响应”,“foo查询API [v2]用JSON响应”]而不是[“foo用JSON响应”,“foo用JSON响应”]在更改之前.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读