【发布时间】:2016-08-29 01:23:46
【问题描述】:
我正在尝试创建一个类似于 Rails assert_difference 的 minitest 断言,但它会检查任何差异,而不仅仅是数字差异。
这是我当前的实现:
Minitest::Assertions.module_eval do
def assert_changed(expression, &block)
unless expression.respond_to?(:call)
expression = lambda{ eval(expression, block.binding) }
end
old = expression.call
block.call
refute_equal old, expression.call
end
end
现在在我的测试套件中,我通过以下方式调用它:
# this is working
username = 'Jim'
assert_changed lambda{ username } do
username = 'Bob'
end
# this is not working
username = 'Jim'
assert_changed 'username' do
username = 'Bob'
end
使用 lambda(或 proc)第一次调用 assert_changed 效果很好。使用带有变量名的字符串的第二次调用不起作用。
当它到达这一行时:expression = lambda{ eval(expression, block.binding) }
我不断收到错误TypeError: no implicit conversion of Proc into String。有人可以向我解释一下如何让它工作吗?
注意:我从 Rails 的 assert_difference 方法中得到了 eval(expression, block.binding) 的想法。
【问题讨论】:
-
虽然我没有看到你在你的问题中这样做,但这看起来确实像你在尝试评估捕获的块时遇到的错误。
-
我猜这是因为你重新定义了变量 expression 然后你在 lambda 中使用
标签: ruby-on-rails ruby lambda metaprogramming proc