测试方法在 Ruby 中调用 super

发布于 2024-10-21 05:49:12 字数 1891 浏览 6 评论 0原文

我有一个测试库来协助测试日志记录:

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.setupteardown 调用 super。有什么想法吗?

I have a testing library to assist in testing logging:

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

回忆那么伤 2024-10-28 05:49:13

我找到了一种方法来做到这一点,这实际上也使测试代码更加简洁!

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文