2

テスト上の理由から、私は最近、DSL ではなくクラス形式を使用するように、いくつかの RSpec マッチャーを移動しました。この形式の場合に連鎖動作を簡単に取得する方法はありますか。

例えば

class BeInZone
  def initialize(expected)
    @expected = expected
  end
  def matches?(target)
    @target = target
    @target.current_zone.eql?(Zone.new(@expected))
  end
  def failure_message
    "expected #{@target.inspect} to be in Zone #{@expected}"
  end
  def negative_failure_message
    "expected #{@target.inspect} not to be in Zone #{@expected}"
  end
  # chain methods here
end

どうもありがとう

4

1 に答える 1

4

chain という名前の新しいメソッドを追加します。通常、このメソッドは を返しselfます。通常、提供された連鎖状態を保存します。次に、使用するmatches?メソッドを更新します。この状態は、さまざまな出力メッセージ メソッドでも使用できます。

あなたの例では:

class BeInZone
  # Your code

  def matches?(target)
    @target = target

    matches_zone? && matches_name?
  end

  def with_name(name)
    @target_name = name
    self
  end

  private
  def matches_zone?
    @target.current_zone.eql?(Zone.new(@expected))
  end

  def matches_name?
    true unless @target_name

    @target =~ @target_name
  end
end

それを使用するには:expect(zoneA_1).to be_in_zone(zoneA).with_name('1')

これが機能する理由は、shouldまたはexpect(object).toメソッドに渡すオブジェクトを構築しているためです。これらのメソッドは、提供されたオブジェクトを呼び出しmatches?ます。

だから、他の Ruby コードのようなものと何ら変わりはありませんputs "hi there".reverse.upcase.gsub('T', '7')。ここで、文字列"hi there"はマッチャーであり、チェーンされたメソッドが呼び出され、から返された最終オブジェクトが に渡さgsubputsます。

組み込みのchangeExpect マッチャーは、確認するのに適した例です。

于 2013-05-02T13:30:11.907 に答える