In Ruby's Test::Unit::TestCase, how do I override the initialize method?

前端 未结 10 1806
再見小時候
再見小時候 2020-12-07 14:54

I\'m struggling with Test::Unit. When I think of unit tests, I think of one simple test per file. But in Ruby\'s framework, I must instead write:

class M         


        
10条回答
  •  时光取名叫无心
    2020-12-07 15:24

    That's how it's supposed to work!

    Each test should be completely isolated from the rest, so the setup and tear_down methods are executed once for every test-case. There are cases, however, when you might want more control over the execution flow. Then you can group the test-cases in suites.

    In your case you could write something like the following:

    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))
    

    The TestDecorator defines a special suite which provides a setup and tear_down method which run only once before and after the running of the set of test-cases it contains.

    The drawback of this is that you need to tell Test::Unit how to run the tests in the unit. In the event your unit contains many test-cases and you need a decorator for only one of them you'll need something like this:

    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)
    

    The Test::Unit documentation documentation provides a good explanation on how suites work.

提交回复
热议问题