我想简化一些测试。具体来说,我想定义一个块断言方法,在块中你可以访问一个特殊的辅助方法,同时还可以访问测试上下文。像这样:
def assert_metric(report, metric, &block)
def sum(value, *filters)
filters.each do |filter|
assert_equal value, report.sum(metric, filter)
end
end
instance_eval(&block)
end
assert_metric report, :select_count do
sum 1
sum 1, :bookmark, :like
sum 0, :vote
end
这样做的正确方法是什么?
约束*:
sum
方法在当前正在执行的测试的上下文中执行(因此您可以执行assert_equal
并访问所有实例变量。sum
在该区块之外无法使用do |test_context|...
)有什么想法吗?
答案 0 :(得分:1)
您似乎假设def sum
的工作方式类似于Python中的嵌套函数。它没有。这将在您的测试类中定义一个方法。没有办法仅在另一个方法中定义方法 - 方法属于类或对象。但是,您可以定义仅存在实现该方法的对象。
如果我正确理解您的要求,最接近的等价物将是:
require 'delegate'
def assert_metric(report, metric, &block)
ctx = SimpleDelegator.new(self)
ctx.singleton_class.class_eval do
define_method(:sum) do
filters.each {|filter| assert_equal value, report.sum(metric, filter)}
end
end
ctx.instance_eval(&block)
end