1

我有一个应该测试 XPath 条件的控制器响应的宏/方法,如下所示:

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 匹配和内置断言效果很好。但是,我有一个测试用例,我希望存在一个匹配元素。这是可选块的工作:向调用者公开 XPath 匹配,以便它可以执行附加的/特定于上下文的断言。

不幸的是,当我真正通过一个街区时:

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

...我收到此错误:

NoMethodError:未定义的方法“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 }

我并不特别喜欢每次都必须(记住)通过测试实例,这就是为什么我希望 Stack Overflow 能够提出更好的答案。

于 2010-02-11T04:47:36.260 回答