开发者

Testing that a method calls super in Ruby

I have a testing library to assist in testing logging:

require 'stringio'

module RedirectIo
  def setup
    $stderr = @stderr = StringIO.new
    $stdin = @stdin = StringIO.new
  开发者_Go百科  $stdout = @stdout = StringIO.new
    super
  end

  def teardown
    $stderr = STDERR
    $stdin = STDIN
    $stdout = STDOUT
    super
  end
end

It is meant to be used like so:

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

Of course, I have a unit test for my test library. :)

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

I'm having trouble figuring out how to test that RedirectIo.setup and teardown call super. Any ideas?


I figured out one way to do it, which actually makes the test code much cleaner as well!

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜