【问题标题】:How do I write methods that insert rspec examples?如何编写插入 rspec 示例的方法?
【发布时间】:2010-10-20 02:32:09
【问题描述】:

在一堆 rspec rails 单元规范中,我执行以下操作:

describe Foo do
  [:bar, :baz].each do |a|
    it "should have many #{a}" do
      Foo.should have_many(a)
    end
  end
end

为了更简洁的代码,我宁愿做这样的事情:

describe Foo do
  spec_has_many Foo, :bar, :baz
end

那么我该如何编写像spec_has_many() 这样的辅助方法来插入像rspec 的it() 方法这样的DSL 代码呢?如果是普通的实例方法,我会这样做:

def spec_has_many(model, *args)
  args.each do |a|
    define_method("it_should_have_many_#{a}") do
      model.should have_many(a)
    end
  end
end

定义 rspec 示例的等价物是什么?

【问题讨论】:

    标签: ruby rspec helpermethods


    【解决方案1】:

    好的,这有点搞砸了,但我想我已经成功了。这有点像元编程黑客,我个人只会使用你描述的第一件事,但这就是你想要的:P

    module ExampleMacros
      def self.included(base)
        base.extend(ClassMethods)
      end
    
      module ClassMethods
        # This will be available as a "Class Macro" in the included class
        def should_have_many(*args)
          args.each do |a|
            # Runs the 'it' block in the context of the current instance
            instance_eval do
              # This is just normal RSpec code at this point
              it "should have_many #{a.to_s}" do
                subject.should have_many(a)
              end
            end
          end
        end
      end
    end
    
    describe Foo do
      # Include the module which will define the should_have_many method
      # Can be done automatically in RSpec configuration (see below)
      include ExampleMacros
    
      # This may or may not be required, but the should_have_many method expects
      # subject to be defined (which it is by default, but this just makes sure
      # it's what we expect)
      subject { Foo }
    
      # And off we go. Note that you don't need to pass it a model
      should_have_many :a, :b
    end
    

    我的规范失败了,因为 Foo 没有 has_many? 方法,但两个测试都运行,所以它应该可以工作。

    您可以在spec_helper.rb 文件中定义(和重命名)ExampleMacros 模块,并且可以将其包含在内。您想在 describe 块中调用 include ExampleMacros(而不是任何其他块)。

    要使您的所有规范自动包含该模块,请像这样配置 RSpec:

    # RSpec 2.0.0
    RSpec.configure do |c|
      c.include ExampleMacros
    end
    

    【讨论】:

      猜你喜欢
      • 2017-08-23
      • 1970-01-01
      • 2022-10-04
      • 2021-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多