当我对我不太信任的代码进行单元测试时,我通常会使用这种模式:
在Ruby的Test :: Unit(我是新手)中,我一直在做这样的事情:
class TestFooBarrer < Test::Unit::TestCase
def setup
@lots_of_objects_to_be_tested = FooBarrer.bar_lots_of_foos
end
def assert_foo_has_been_barred(foo)
assert_kind_of Bar, foo
end
def assert_foo_has_baz_method(foo)
assert_respond_to foo, :baz
end
#Many more assertions along those lines go here.
def test_all_theories
@lots_of_objects_to_be_tested.each do |foo|
assert_foo_has_been_barred(foo)
assert_foo_has_baz_method(foo)
# etc.
#
end
end
end
当我正在测试的理论数量达到数十个时,这显然有点笨拙,并且涉及到我看起来像许多不必要的重复。我宁愿做这样的事情:
class FooTheories
def self.assert_all_theories(foo)
# ???
end
def assert_foo_has_been_barred(foo)
assert_kind_of Bar, foo
end
def assert_foo_has_baz_method(foo)
assert_respond_to foo, :baz
end
#Many more assertions along those lines go here.
end
class TestFooBarrer < Test::Unit::TestCase
def setup
@lots_of_objects_to_be_tested = FooBarrer.bar_lots_of_foos
end
def test_all_theories
@lots_of_objects_to_be_tested.each do |foo|
FooTheories.assert_all_theories(foo)
end
end
end
基本上,我正在寻找一种在一个地方写一堆断言的方法,然后在大量的对象上反复调用它们。
Ruby中有类似的东西吗?我并不特别关注Test :: Unit。任何测试框架都可以。
答案 0 :(得分:1)
我要做的是即时生成测试。在test_helper中添加一个方法:
def test(obj, &block)
define_method("test_#{ obj.to_s }", &block)
end
然后你可以使你的测试套件如下
class TestObjects < Test::Unit::TestCase
@objects_to_test = [...]
@objects_to_test.each do |obj|
test obj do
assert obj.is_a?(Foo), 'not a foo'
# all assertions here
end
end
end
然后,如果失败,您将知道哪个对象失败,因为测试的名称是对象的字符串表示。前消息:
1) Failure:
test_#<Bar:0x000001009ee930>(TestObjects):
not a foo