如何解决如何在Ruby中创建和使用由字符串值动态命名的变量? 关于发送:警告!
我正在使用SitePrism创建一些POM测试。我的页面类别之一如下:
class HomePage < SitePrism::Page
set_url '/index.html'
element :red_colour_cell,"div[id='colour-cell-red']"
element :green_colour_cell,"div[id='colour-cell-green']"
element :blue_colour_cell,"div[id='colour-cell-blue']"
def click_colour_cell(colour)
case colour
when 'red'
has_red_colour_cell?
red_colour_cell.click
when 'green'
has_green_colour_cell?
green_colour_cell.click
when 'blue'
has_blue_colour_cell?
blue_colour_cell.click
end
end
end
方法click_colour_cell()
从调用此方法的Capybara测试步骤获取其字符串值。
如果将来我需要创建其他类似的方法,那么用这么多的大小写开关来确定代码流可能会变得很繁琐和笨拙。
是否可以通过某种方式创建由另一个变量的字符串值动态命名的变量?例如,我想为click_colour_cell()
做一些类似于以下的事情:
def click_colour_cell(colour)
has_@colour_colour_cell?
@colour_colour_cell.click
end
其中@colour
表示传递的值colour
的值,将由Ruby解释:
def click_colour_cell('blue')
has_blue_colour_cell?
blue_colour_cell.click
end
这不是用于什么实例变量的吗?我尝试了上述建议作为解决方案,但收到了模棱两可的错误:
Syntax error,unexpected end,expecting ':'
end
^~~ (SyntaxError)
如果它是我需要使用的实例变量,那么我不确定是否正确使用了它。如果我还需要使用其他东西,请告知。
解决方法
使用实例变量定义对象的属性。
相反,您可以通过方法send和字符串插值来实现。
请尝试以下操作:
def click_colour_cell(colour)
send("has_#{colour}_colour_cell?")
send("#{colour}_colour_cell").click
end
关于发送:
send
是Object
类(所有类的父类)中定义的方法。
正如documentation所说,它调用由给定的String或Symbol标识的方法。您还可以将参数传递给尝试调用的方法。
在下面的代码段中,send将搜索名为testing
的方法并调用它。
class SendTest
def testing
puts 'Hey there!'
end
end
obj = SendTest.new
obj.send("testing")
obj.send(:testing)
输出
Hey there!
Hey there!
在您的情况下,考虑为colour
传递的参数为blue
,
"has_#{colour}_colour_cell?"
将返回字符串"has_blue_colour_cell?"
,并且send将动态调用名为has_blue_colour_cell?
的方法。方法blue_colour_cell
直接回答您的问题
您可以使用以下方法动态获取/设置实例变量:
instance_variable_get("@build_string_as_you_see_fit")
instance_variable_set("@build_string_as_you_see_fit",value_for_ivar)
但是...
警告!
我认为在此处动态创建变量和/或在send
中使用字符串构建方法名称之类的方法是一个坏主意,它将极大地阻碍将来的可维护性。
这样想:每次您看到这样的方法名称:
click_blue_button
click_red_button
click_green_button
这和做的事情是一样的
add_one_to(1) // instead of 1 + 1,i.e. 1.+(1)
add_two_to(1) // instead of 1 + 2,i.e. 1.+(2)
add_three_to(1) // instead of 1 + 3,i.e. i.+(3)
您没有将有意义的参数传递给方法,而是将值硬编码为方法名称!继续此操作,最终您的整个代码库将不得不处理已硬编码到方法名称中的“值”。
更好的方法
这是您应该做的:
class HomePage < SitePrism::Page
set_url '/index.html'
elements :color_cells,"div[id^='colour-cell-']"
def click_cell(color)
cell = color_cells.find_by(id: "colour-cell-#{color}") # just an example,I don't know how to do element queries in site-prism
cell.click
end
end
或者如果您必须将它们作为单独的元素:
class HomePage < SitePrism::Page
set_url '/index.html'
COLORS = %i[red green blue]
COLORS.each do |color|
element :"#{color}_colour_cell","div[id='colour-cell-#{color}']"
end
def cell(color:) # every other usage should call this method instead
@cells ||= COLORS.index_with do |color|
send("#{color}_colour_cell") # do the dynamic `send` in only ONE place
end
@cells.fetch(color)
end
end
home_page.cell(color: :red).click
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。