2010-02-11 5 views
1

У меня есть Shoulda макрос/метод, который проверяет ответы контроллера для условий 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 и встроенного утверждение отлично работает. Тем не менее, у меня есть одна тестовая ячейка, где я хочу точно один элемент соответствия для существования. Это задание необязательного блока: выведите соответствие XPath вызывающему, чтобы он мог выполнять дополнительные/контекстно-зависимые утверждения.

К сожалению, когда я на самом деле передать блок:

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

... Я получаю эту ошибку:

NoMethodError: undefined method `assert_equal' for Users::SessionsControllerTest:Class

Это (как я понимаю) из-за способа Shoulda работы: параметры, переданные на вызов «должен» (включая блок), определяются в контексте тестового класса, а не в экземпляре тестового класса. Test :: Unit :: Assertions.assert * - это методы экземпляра модуля, поэтому я не могу получить к ним доступ удобно.

Итак, мой вопрос: есть ли удобный/идиоматический способ доступа к методам assert * из Test :: Unit :: Assertions без особых проблем? Решение должно работать с Shoulda, хотя необязательно должно быть зависимым на Shoulda; прямой путь Ruby был бы прекрасен.

ответ

1

Это должно работать, как вы хотите, чтобы:

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

совершенен! Спасибо, пучок. –

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 } 

Я не особенно нравится необходимость (не забудьте) передать экземпляр теста каждый раз, поэтому я надеюсь, что переполнение стека будет иметь чтобы получить лучший ответ.