とりあえずコードだけ。
money.py
#!/usr/bin/env python # coding: utf-8 """テスト駆動開発入門 13章 動作 """ class Expression(object): def reduce(self, currency_to): pass class Money(Expression): def __init__(self, amount, currency): self._amount = amount self._currency = currency def times(self, multiplier): return Money(self._amount * multiplier, self._currency) @staticmethod def dollar(amount): return Money(amount, "USD") @staticmethod def franc(amount): return Money(amount, "CHF") def currency(self): return self._currency def reduce(self, currency_to): return self def __eq__(self, other): return self._amount == other._amount and \ self.currency() == other.currency() def __repr__(self): """デバッグ用出力文字列 """ return str(self._amount) + " " + str(self._currency) def __add__(self, addend): return Sum(self, addend) class Bank(object): def reduce(self, source, currency_to): return source.reduce(currency_to) class Sum(Expression): def __init__(self, augend, addend): self.augend = augend self.addend = addend def reduce(self, currency_to): amount = self.augend._amount + self.addend._amount return Money(amount, currency_to)
money_test.py
#!/usr/bin/env python # coding: utf-8 """テスト駆動開発入門 13章 動作 """ import unittest from money import * class TestMoney(unittest.TestCase): """moneyモジュールのテスト """ def testMultiplication(self): """かけ算のテスト """ five = Money.dollar(5) self.assertEqual(Money.dollar(10), five.times(2) ) self.assertEqual(Money.dollar(15), five.times(3) ) def testFrancMultiplication(self): """Francクラスのかけ算のテスト """ five = Money.franc(5) self.assertEqual(Money.franc(10), five.times(2) ) self.assertEqual(Money.franc(15), five.times(3) ) def testEuality(self): """同値テスト """ self.assert_( Money.dollar(5) == Money.dollar(5) ) self.assert_(not Money.dollar(5) == Money.dollar(6) ) self.assert_(not Money.franc(5) == Money.dollar(5) ) def testCurrency(self): """通貨単位のテスト """ self.assertEqual("USD", Money.dollar(1).currency() ) self.assertEqual("CHF", Money.franc(1).currency() ) def testSimpleAddition(self): """足し算のテスト """ five = Money.dollar(5) sum = five + five self.assert_(Money.dollar(10), sum) bank = Bank() reduced = bank.reduce(sum, "USD") self.assertEqual(Money.dollar(10), reduced) def testPlusReturnsSum(self): five = Money.dollar(5) result = five + five sum = result self.assertEqual(five, sum.addend) self.assertEqual(five, sum.augend) def testReduceSum(self): sum = Sum(Money.dollar(3), Money.dollar(4) ) bank = Bank() result = bank.reduce(sum, "USD") self.assertEqual(Money.dollar(7), result) def testReduceMoney(self): bank = Bank() result = bank.reduce(Money.dollar(1), "USD") self.assertEqual(Money.dollar(1), result) if __name__ == "__main__": unittest.main()