1

次のようなXPath条件に対するコントローラーの応答をテストするshouldaマクロ/メソッドがあります。

def self.should_have_xpath(path, &block)
  should "have an element matching the path: #{path}" do
    xml = REXML::Document.new @response.body
    match = XPath.match(xml, path)
    if block_given?
      yield match
    else
      assert match.size != 0, "No nodes matching '#{path}'"
    end
  end
end

XPathマッチングと組み込みアサーションはうまく機能します。ただし、一致要素を1つだけ存在させたいテストケースが1つあります。これはオプションのブロックの仕事です。XPathの一致を呼び出し元に公開して、追加の/コンテキスト固有のアサーションを実行できるようにします。

残念ながら、実際にブロックを渡すと、次のようになります。

should_have_xpath("//my/xpath/expression") { |match| assert_equal 1, match.size }

...このエラーが発生します:

NoMethodError:Users :: SessionsControllerTest:Classの未定義のメソッド `assert_equal'

これは(私が理解しているように)Shouldaの動作方法によるものです。「should」呼び出し(ブロックを含む)に渡されるパラメーターは、テストクラスのインスタンスではなく、テストクラスのコンテキストで定義されます。Test :: Unit :: Assertions.assert *はモジュールインスタンスメソッドであるため、便利にアクセスできません。

だから、私の質問は:Test :: Unit :: Assertionsからassert*メソッドにあまり問題なくアクセスするための便利で慣用的な方法はありますか?ソリューションはShouldaで機能する必要がありますが、Shouldaに依存する必要はありません。まっすぐなRubyの方法で十分です。

4

2 に答える 2

1

これは、希望どおりに機能するはずです。

def self.should_have_xpath(path, &block)
  should "have an element matching the path: #{path}" do
    # ...
    block.bind(self).call(match)
  end
end
于 2010-02-11T06:24:08.687 に答える
0

私は実用的な解決策を持っています:

def self.should_have_xpath(path, &block)
  should "have an element matching the path: #{path}" do
    # ...
    yield match, self
  end
end

should_have_xpath( "//my/xpath/expression" ) { |match, test | test.assert_equal 1, match.size }

毎回テストインスタンスに合格する必要がある(覚えておく)のは特に好きではありません。そのため、StackOverflowがより良い答えを見つけられることを期待しています。

于 2010-02-11T04:47:36.260 に答える