テスト駆動開発入門のxUnitの例をrubyで書いてみた

最近読んでいる Kent Beckの『テスト駆動開発入門』の写経を
id:t-wadaさんに影響されてやってみた。

本自体は、いいと思うものの日本語がかなり難しい。。
意味が分からないところがかなりある。
英語版の方もこんなに難しいの?と疑問。

有名なMoneyの例をjavaで写経した後に
xUnitの例をpythonで写経して、
気分転換でRubyで改めて写経。

Ruby最近まったくやってないながら、
恥覚悟でコードはっておきます。

# xUnitの例をRubyで実装

# rubyにassertないっぽいので。。。
def assert(exp)
  raise "assert:" unless exp
end

def assert_equals(exp1, exp2)
  raise "assert:" unless exp1 == exp2
end

class TestSuite
  attr_accessor :tests

  def initialize
    @tests = []
  end
 
  def add(test)
    @tests.push(test)
  end

  def run(result)
    @tests.each { |test|
      test.run(result)
    }
  end
end

class TestResult
  attr_accessor :runCount
  attr_accessor :errorCount

  def initialize
    @runCount = 0
    @errorCount = 0
  end

  def testStarted
    @runCount = @runCount + 1
  end

  def testFailed
    @errorCount = @errorCount + 1
  end

  def summary
    return sprintf("%d run, %d failed", @runCount, @errorCount)
  end

end

class TestCase
   attr_accessor :name

   def initialize(name)
     @name = name
   end

   def run(result)
     result.testStarted()
     setUp()
     begin
       __send__(@name)
     rescue
       result.testFailed()
     end
     tearDown()
   end

   def setUp
   end

   def tearDown
   end

end

class WasRun < TestCase
  attr_accessor :log

  def initialize(name)
    @wasRun = nil
    super(name)
  end

  def testMethod
    @log = @log + "testMethod "
  end

  def setUp
    @log = "setUp "
  end

  def tearDown
    @log = @log + "tearDown "
  end

  def testBrokenMethod
    raise
  end
end

class TestCaseTest < TestCase
  attr_accessor :result

  def setUp
    @result = TestResult.new
  end

  def testTemplateMethod
    test = WasRun.new("testMethod")
    test.run(@result)
    assert("setUp testMethod tearDown " == test.log)
  end

  def testResult
    test = WasRun.new("testMethod")
    test.run(@result)
    assert("1 run, 0 failed" == result.summary())
  end

  def testFailedResult
    test = WasRun.new("testBrokenMethod")
    test.run(@result)
    assert_equals("1 run, 1 failed", @result.summary())
  end

  def testFailedResultFormatting
    @result.testStarted()
    @result.testFailed()
    assert("1 run, 1 failed" == @result.summary())
  end

  def testSuite
    suite = TestSuite.new
    suite.add(WasRun.new("testMethod"))
    suite.add(WasRun.new("testBrokenMethod"))
    suite.run(@result)
    assert("2 run, 1 failed" == @result.summary())
  end

end

# テスト実行
suite = TestSuite.new
suite.add(TestCaseTest.new("testTemplateMethod"))
suite.add(TestCaseTest.new("testResult"))
suite.add(TestCaseTest.new("testFailedResultFormatting"))
suite.add(TestCaseTest.new("testFailedResult"))
suite.add(TestCaseTest.new("testSuite"))
result = TestResult.new
suite.run(result)
print result.summary() , "\n"