我有一个测试库来帮助测试日志记录:
require 'stringio'
module RedirectIo
def setup
$stderr = @stderr = StringIO.new
$stdin = @stdin = StringIO.new
$stdout = @stdout = StringIO.new
super
end
def teardown
$stderr = STDERR
$stdin = STDIN
$stdout = STDOUT
super
end
end
它意味着像这样使用:
require 'lib/redirect_io'
class FooTest < Test::Unit::TestCase
include RedirectIo
def test_logging
msg = 'bar'
Foo.new.log msg
assert_match /^#{TIMESTAMP_REGEX} #{msg}$/, @stdout.string, 'log message'
end
end
当然,我对我的测试库进行了单元测试。 :)
require 'lib/redirect_io'
class RedirectIoTest < Test::Unit::TestCase
def test_setup_and_teardown_are_mixed_in
%W{setup teardown}.each do |method|
assert_not_equal self.class, self.class.new(__method__).method(method).owner, "owner of method #{method}"
end
self.class.class_eval { include RedirectIo }
%W{setup teardown}.each do |method|
assert_equal RedirectIo, self.class.new(__method__).method(method).owner, "owner of method #{method}"
end
end
def test_std_streams_captured
%W{STDERR STDIN STDOUT}.each do |stream_name|
assert_equal eval(stream_name), self.class.new(__method__).instance_eval("$#{stream_name.downcase}"), stream_name
end
self.class.class_eval { include RedirectIo }
setup
%W{STDERR STDIN STDOUT}.each do |stream_name|
assert_not_equal eval(stream_name), self.class.new(__method__).instance_eval("$#{stream_name.downcase}"),
stream_name
end
teardown
%W{STDERR STDIN STDOUT}.each do |stream_name|
assert_equal eval(stream_name), self.class.new(__method__).instance_eval("$#{stream_name.downcase}"), stream_name
end
end
end
我无法弄清楚如何测试 RedirectIo.setup 和拆解调用super。有什么想法吗?
答案 0 :(得分:1)
我想出了一种方法,它实际上使测试代码更加清晰!
require 'lib/redirect_io'
class RedirectIoTest < Test::Unit::TestCase
class RedirectIoTestSubjectSuper < Test::Unit::TestCase
def setup
@setup = true
end
def teardown
@teardown = true
end
end
class RedirectIoTestSubject < RedirectIoTestSubjectSuper
include RedirectIo
def test_fake; end
end
def test_setup_and_teardown_are_mixed_in
%W{setup teardown}.each do |method|
assert_not_equal RedirectIoTestSubject, self.method(method).owner, "owner of method #{method}"
end
%W{setup teardown}.each do |method|
assert_equal RedirectIo, RedirectIoTestSubject.new(:test_fake).method(method).owner, "owner of method #{method}"
end
end
def test_std_streams_captured
obj = RedirectIoTestSubject.new(:test_fake)
$stderr = STDERR
$stdin = STDIN
$stdout = STDOUT
obj.setup
%W{STDERR STDIN STDOUT}.each do |stream_name|
assert_not_equal eval(stream_name), eval("$#{stream_name.downcase}"), stream_name
end
obj.teardown
%W{STDERR STDIN STDOUT}.each do |stream_name|
assert_equal eval(stream_name), eval("$#{stream_name.downcase}"), stream_name
end
end
def test_setup_and_teardown_call_super
obj = RedirectIoTestSubject.new(:test_fake)
obj.setup
assert obj.instance_eval{@setup}, 'super called?'
obj.teardown
assert obj.instance_eval{@teardown}, 'super called?'
end
end