Ruby中如何将字符串转为对应谓词方法名简化URL校验断言
Ruby 测试场景下动态调用校验方法的实现方案
完全可以实现,不需要额外封装复杂的链式调用逻辑,借助Ruby原生的动态方法调用能力就能直接消掉原来的三元判断分支。
你现在的核心需求,其实就是根据传入的state字符串,拼出对应的校验方法名,在测试目标对象上执行对应的判断逻辑。
直接用Ruby内置的public_send就能搞定,原来那行冗长的三元断言,直接替换成这行就行:
assert new_product(image_url).public_send("#{state}?")
执行逻辑说明
- 代码运行时会自动把传入的
state值,拼接上Ruby校验方法通用的?后缀:state为"valid"时,拼出的方法名是"valid?";state为"invalid"时,拼出的方法名是"invalid?" public_send会拿着拼好的方法名,在new_product(image_url)返回的对象上调用对应的公开实例方法,最终的执行结果和你原来写的三元判断逻辑完全一致。
改写后的完整validate_url函数可以简化成这样:
def validate_url(image_url, state) test_product = new_product(image_url) assert test_product.public_send("#{state}?"), "#{image_url} should always be " + state.upcase end
实际开发的注意点
- 优先用
public_send,不要用旧的send:send可以绕过访问限制调用私有方法,测试场景下我们本来就是要验证公开的校验逻辑,用public_send能避免误触发非预期的私有逻辑,测试结果更可靠 - 可以补一行简单的入参校验,避免测试时手滑传错参数,最后抛个模糊的“方法不存在”错误:
可选的入参防护逻辑:
# 加在函数最开头 unless %w[valid invalid].include?(state.to_s) raise ArgumentError, "state 参数只支持传 valid / invalid 两个值" end - 你之前预想的那种
new_product(image_url).state.xxx?的链式写法完全没必要做,这种写法在测试场景里既不简洁,还要额外做对象封装,徒增代码量,直接用public_send动态调用就是最贴合Ruby开发习惯的实现方式。
内容的提问来源于stack exchange,提问作者caramba
相关产品推荐
相关产品推荐

