테스트 주도 개발 | 2장 타락한 객체

날짜
May 22, 2024
태그
TDD
python
설명
 

TODO LIST

$5 + 10CHF = $10(환율이 2:1)일 경우
$5 X 2 = $10
amount를 private 만들기
Dollar 부작용
Money 반올림
 
테스트를 통과했지만 이상하다. Dollar에 대해 연산을 수행한 이후 해당 Dollar의 값이 바뀐다는 것이다. 다음과 같이 사용하기를 바란다.
 
class TestDollar(TestCase): def test_multiplication(self): five = Dollar(5) five.times(2) self.assertEqual(10, five.amount) five.times(3) self.assertEqual(15, five.amount)
Dollar의 연산이 수행되고 다시 연산을 수행한다.
>>> python moneyapp/manage.py test moneys Creating test database for alias 'default'... System check identified no issues (0 silenced). F ====================================================================== FAIL: test_multiplication (moneys.tests.TestDollar) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/googie/Desktop/TDD-example/moneyapp/moneys/tests.py", line 17, in test_multiplication self.assertEqual(15, five.amount) AssertionError: 15 != 30 ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (failures=1) Destroying test database for alias 'default'...
생각한 값이 나오지 않는다.
 
times를 거친 five 객체는 더이상 5가 아니다. 그럼 times() 메서드에서 새로운 객체를 반환하게 만들면 어떨까? 온종일 곱셈을 해도 5를 반환하게 만들면 되지 않을까.
class TestDollar(TestCase): def test_multiplication(self): five = Dollar(5) product = five.times(2) self.assertEqual(10, product.amount) product = five.times(3) self.assertEqual(15, product.amount)
새로운 객체를 만들어 테스트한다.
>>> python moneyapp/manage.py test moneys Creating test database for alias 'default'... System check identified no issues (0 silenced). E ====================================================================== ERROR: test_multiplication (moneys.tests.TestDollar) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/googie/Desktop/TDD-example/moneyapp/moneys/tests.py", line 15, in test_multiplication self.assertEqual(10, product.amount) AttributeError: 'NoneType' object has no attribute 'amount' ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (errors=1) Destroying test database for alias 'default'...
amount가 반환하는 값이 없어 에러가 발생한다.
class Dollar: def __init__(self, amount: int): self.amount = amount def times(self, multiplier: int): return Dollar(self.amount * multiplier)
새로운 객체를 반환하도록 수정했다.
>>> python moneyapp/manage.py test moneys Creating test database for alias 'default'... System check identified no issues (0 silenced). . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK Destroying test database for alias 'default'...
테스트가 통과했다.
 

TODO LIST

$5 + 10CHF = $10(환율이 2:1)일 경우
$5 X 2 = $10
amount를 private 만들기
Dollar 부작용
Money 반올림
 
  • 설계상의 결함(Dollar 부작용)으로 인해 실패하는 테스트로 변환했다.
  • 스텁 구현으로 빠르게 테스트가 가능한 코드를 만들었다.
  • 올바르다고 생각하는 코드를 입력해 테스트를 통과시켰다.

댓글

guest