目指そうかなRubyist RSSフィード

 | 

2011-06-21

[meta] TimeDateに依存したコードのテストをどう書くか?  [meta] TimeやDateに依存したコードのテストをどう書くか? - 目指そうかなRubyist を含むブックマーク はてなブックマーク -  [meta] TimeやDateに依存したコードのテストをどう書くか? - 目指そうかなRubyist  [meta] TimeやDateに依存したコードのテストをどう書くか? - 目指そうかなRubyist のブックマークコメント

class Loan
  def initialize(book)
    @book = book
    @time = Time.now
  end

  def to_s
    "#{@book.upcase} loaded on #{@time}"
  end
end

上記のコードではTime.nowが邪魔してテストできない。

次の用にコードを帰る

class Loan
  def initialize(book)
    @book = book
    @time = Loan.time_class.now
  end

  def self.time_class
    @time_class || Time
  end

  def to_s
    "#{@book.upcase} loaded on #{@time}"
  end
end

実際に使う際には、@time_classは常にnilになるので、Timeが呼ばれる。テストコードでは、@time_classにダミーの時間を挿入してテストすると良い。以下、テストコード

require 'test/unit'
class FakeTime
  def self.now
    '2011-06-21 21:14:44 +0900'
  end
end

class Test_Loan < Test::Unit::TestCase
  def test_conversion_to_string
    Loan.instance_eval { @time_class = FakeTime }
    loan = Loan.new('War and Peace')
    assert_equal "WAR AND PEACE loaded on #{FakeTime.now}", loan.to_s
  end
end
 |