Ruby 我可以别名RSpec匹配器吗?

Ruby 我可以别名RSpec匹配器吗?,ruby,rspec,Ruby,Rspec,我有两个匹配者,除了他们的名字外,他们是一样的: RSpec::Matchers.define :be_the_downcased_version_of do |actual| match do |actual| @actual = actual @expected = expected @actual == @expected.downcase end failure_message do |actual|

我有两个匹配者,除了他们的名字外,他们是一样的:

RSpec::Matchers.define :be_the_downcased_version_of do |actual|
    match do |actual|
        @actual = actual
        @expected = expected

        @actual == @expected.downcase
    end

    failure_message do |actual|
        "Expected #{@actual.inspect} to be the downcased version of #{expected.inspect}.\nIt was not: #{@actual.inspect}"
    end

    failure_message_when_negated do |actual|
        "Expected #{@actual.inspect} to not be the downcased version of #{expected.inspect}.\nIt was: #{@actual.inspect}"
    end

    description do
        "be the downcased version of #{expected.inspect}"
    end
end

RSpec::Matchers.define :return_the_downcased_version_of do |actual|
    match do |actual|
        @actual = actual
        @expected = expected

        @actual == @expected.downcase
    end

    failure_message do |actual|
        "Expected #{@actual.inspect} to be the downcased version of #{expected.inspect}.\nIt was not: #{@actual.inspect}"
    end

    failure_message_when_negated do |actual|
        "Expected #{@actual.inspect} to not be the downcased version of #{expected.inspect}.\nIt was: #{@actual.inspect}"
    end

    description do
        "be the downcased version of #{expected.inspect}"
    end
end
我可以像在用Ruby给方法加别名时那样给它们加别名吗

alias_method :foo_meth, :bar_meth

是的,您可以为使用RSpec的matcher DSL定义的matcher设置别名。我所知道的最方便的方法是在块之前的
中重新打开示例上下文的类,并在那里别名该方法

但首先,让我们清理一下你的媒人

  • 传递给
    匹配器的块。define
    采用预期值,而不是 实际值,作为其参数
  • 您不需要这些实例变量;它们的值已在块参数中可用
  • 在spec/support/be_.rb的\u downcased \u版本中:

    RSpec::Matchers.define :be_the_downcased_version_of do |expected|
      match do |actual|
        actual == expected.downcase
      end
    
      failure_message_for_should do |actual|
        "Expected #{actual.inspect} to be the downcased version of #{expected.inspect}.\nIt was not: #{actual.inspect}"
      end
    
      failure_message_for_should_not do |actual|
        "Expected #{actual.inspect} to not be the downcased version of #{expected.inspect}.\nIt was: #{actual.inspect}"
      end
    
      description do
        "be the downcased version of #{expected.inspect}"
      end
    
    end
    
    alias_method :return_the_downcased_version_of, :be_the_downcased_version_of
    
    def be_the_downcased_version_of(actual)
      BeTheDowncasedVersionOf.new actual
    end
    
    class BeTheDowncasedVersionOf
      def initialize(expected)
        @expected = expected
      end
    
      def matches?(actual)
        @actual = actual
        @actual == @expected.downcase
      end
    
      def failure_message_for_should
        "Expected #{@actual.inspect} to be the downcased version of #{@expected.inspect}.\nIt was not: #{@actual.inspect}"
      end
    
      def failure_message_for_should_not
        "Expected #{@actual.inspect} to not be the downcased version of #{@expected.inspect}.\nIt was: #{@actual.inspect}"
      end
    
      def description
        "be the downcased version of #{@expected.inspect}"
      end
    
    end
    
    要在spec/spec_helper.rb中别名该匹配器定义的方法,请执行以下操作:

    config.before :each do
      class << self
        alias_method :return_the_downcased_version_of, :be_the_downcased_version_of
      end
    end
    

    正如CB利亚德所评论的,你可以简单地做到

    RSpec::Matchers.define :be_the_downcased_version_of do |expected|
      match do |actual|
        # ...
      end
      # ...
    end
    
    RSpec::Matchers.alias_matcher :return_the_downcased_version_of, :be_the_downcased_version_of
    

    化名为匹配者。在我看来,这是一种非常干净的解决方案。

    另一种替代方法是使用。然后可以编写
    RSpec::Matchers.alias\u matcher:return\u downcased\u version\u of,:be\u downcased\u version\u of