Search code examples
rubyunit-testingreflectiontestunit

Object.respond_to? fails when retrieving method name symbol from array


I'm implementing page objects, and writing tests to verify them. I want to simplify the tests by storing the element names in an array of symbols and looping through it, but it's failing.

def setup
  @browser = Watir::Browser.new :phantomjs
  @export_page = ExportPage.new @browser
  @assets = %i{:section :brand}
end

--

#PASSES

def test_static
    $stdout.puts :section.object_id
    raise PageElementSelectorNotFoundException, :section unless @export_page.respond_to? :section
end

> # 2123548

This passes because the target class does implement this method, however:

#FAILS

def test_iterator
  @assets.each do |selector|
    $stdout.puts selector.class
    $stdout.puts selector.object_id
    $stdout.puts :section.object_id
    raise PageElementSelectorNotFoundException, selector unless @export_page.respond_to? selector
  end
end


> # Testing started at 11:19 ...
> # Symbol
> # 2387188
> # 2123548

PageElementSelectorNotFoundException: :section missing from page
~/src/stories/test/pages/export_page_test.rb:20:in `block in test_iterator'

As you can see, I've checked the object ids of the symbols and they do seem to be different. Could this be why it's failing? Is there a solution to this?


Solution

  • When using short notation to declare an array of atoms, one should not put colons there:

    - %i{:section :brand}   # incorrect
    + %i{section brand}     # correct
    

    What you have actually defined by @assets = %i{:section :brand}, is the following array:

    [:':section', :':brand']