Rogue_Leader Rogue_Leader - 6 months ago 14
Ruby Question

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?

Answer

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']