当前位置:  开发笔记 > 后端 > 正文

在Ruby的Test :: Unit :: TestCase中,如何覆盖initialize方法?

如何解决《在Ruby的Test::Unit::TestCase中,如何覆盖initialize方法?》经验,为你挑选了3个好方法。

我正在与Test :: Unit挣扎.当我想到单元测试时,我想到了每个文件的一个简单测试.但是在Ruby的框架中,我必须改为:

class MyTest < Test::Unit::TestCase 
   def setup 
   end

   def test_1 
   end

   def test_1 
   end
end

但是每次调用test_*方法都会运行setup和teardown.这正是我不想要的.相反,我想要一个只为整个类运行一次的设置方法.但我似乎无法在不破坏TestCase初始化的情况下编写自己的initialize().

那可能吗?或者我是否使这无可救药地变得复杂?



1> Matt Wolfe..:

正如Hal Fulton的书"The Ruby Way"中所提到的那样.他重写了Test :: Unit的self.suite方法,它允许类中的测试用例作为套件运行.

def self.suite
    mysuite = super
    def mysuite.run(*args)
      MyTest.startup()
      super
      MyTest.shutdown()
    end
    mysuite
end

这是一个例子:

class MyTest < Test::Unit::TestCase
    class << self
        def startup
            puts 'runs only once at start'
        end
        def shutdown
            puts 'runs only once at end'
        end
        def suite
            mysuite = super
            def mysuite.run(*args)
              MyTest.startup()
              super
              MyTest.shutdown()
            end
            mysuite
        end
    end

    def setup
        puts 'runs before each test'
    end
    def teardown
        puts 'runs after each test'
    end 
    def test_stuff
        assert(true)
    end
end



2> Rômulo Cecco..:

这就是它应该如何工作!

每个测试应该与其余测试完全隔离,因此每个测试用例都会执行一次setuptear_down方法.但是,有些情况下,您可能希望更多地控制执行流程.然后,您可以在套件中对测试用例进行分组.

在您的情况下,您可以编写如下内容:

require 'test/unit'
require 'test/unit/ui/console/testrunner'

class TestDecorator < Test::Unit::TestSuite

  def initialize(test_case_class)
    super
    self << test_case_class.suite
  end

  def run(result, &progress_block)
    setup_suite
    begin
      super(result, &progress_block)      
    ensure
      tear_down_suite
    end
  end

end

class MyTestCase < Test::Unit::TestCase

  def test_1
    puts "test_1"
    assert_equal(1, 1)
  end

  def test_2
    puts "test_2"
    assert_equal(2, 2)
  end

end

class MySuite < TestDecorator

  def setup_suite
    puts "setup_suite"
  end

  def tear_down_suite
    puts "tear_down_suite"
  end

end

Test::Unit::UI::Console::TestRunner.run(MySuite.new(MyTestCase))

TestDecorator定义了一个特殊套件,它提供了一个setuptear_down其前和一组包含的测试用例的运行后只运行一次的方法.

这样做的缺点是你需要告诉Test :: Unit如何在单元中运行测试.如果您的单元包含许多测试用例,并且您只需要其中一个的装饰器,则需要以下内容:

require 'test/unit'
require 'test/unit/ui/console/testrunner'

class TestDecorator < Test::Unit::TestSuite

  def initialize(test_case_class)
    super
    self << test_case_class.suite
  end

  def run(result, &progress_block)
    setup_suite
    begin
      super(result, &progress_block)      
    ensure
      tear_down_suite
    end
  end

end

class MyTestCase < Test::Unit::TestCase

  def test_1
    puts "test_1"
    assert_equal(1, 1)
  end

  def test_2
    puts "test_2"
    assert_equal(2, 2)
  end

end

class MySuite < TestDecorator

  def setup_suite
    puts "setup_suite"
  end

  def tear_down_suite
    puts "tear_down_suite"
  end

end

class AnotherTestCase < Test::Unit::TestCase

  def test_a
    puts "test_a"
    assert_equal("a", "a")
  end

end

class Tests

  def self.suite
    suite = Test::Unit::TestSuite.new
    suite << MySuite.new(MyTestCase)
    suite << AnotherTestCase.suite
    suite
  end

end

Test::Unit::UI::Console::TestRunner.run(Tests.suite)

测试::单位文档文件提供了有关如何套房工作一个很好的解释.



3> jpgeek..:

最后,测试单元实现了这一点!活泉! 如果您使用的是v 2.5.2或更高版本,则可以使用:

Test::Unit.at_start do
  # initialization stuff here
end

当您开始测试时,这将运行一次.除了在每次测试(设置)之前运行的回调之外,还有在每个测试用例(启动)开始时运行的回调.

http://test-unit.rubyforge.org/test-unit/en/Test/Unit.html#at_start-class_method

推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有