2011-03-08 62 views
0

调用super我有一个测试库,以协助测试记录:测试一个方法在Ruby中

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拆卸调用超。有任何想法吗?

+1

也许StringIO自从我使用的Ruby版本发生了变化,但在我的机器上,除非您手动从StringIO实例中提取字符串,否则测试将不起作用。与@ stdout.string。 – matt 2011-04-29 18:19:14

+0

谢谢,马特。该监督已得到纠正。 – 2011-05-01 08:23:06

回答

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 
相关问题