Skip to content

Wo-ogie/tdd-point-management

Repository files navigation

TDD로 개발하기

How to TDD

  1. 기능 구현을 원하는 요구사항을 검증하는 테스트 추가
  2. 테스트를 만족하도록 기능 구현
    • 이 때, 테스트는 한번에 많은 Scope 를 잡지 않는다. 이는 불필요한 개발 생산성 저하로 이어진다.
    • 이 시점에서 우리가 몇 배의 시간을 더 투자한다고 해서 테스트 커버리지 100% 를 달성할 수는 없다.
  3. 구현된 기능에 대한 리팩토링 (인터페이스 구성, 코드 클리닝 등 코드 베이스 정리)

요구사항

Testable Code

  • 모든 코드를 테스트 가능하게 구현하는 것을 목표로 진행합니다.
  • 모든 테스트 케이스가 성공했다는 것은 목표한 기능이 완성되었다는 것을 의미합니다.
  • 테스트 커버리지 100% 가 아니라, 정확히 기능의 동작을 확인하는 테스트를 작성해 주세요.
  • 주요 기능에서 private 접근자, 객체간의 강결합 같이 테스트 불가능한 코드는 가능한 한 지양하는 것이 좋습니다.

point package의 TODO와 test code를 작성한다.

  • PATCH /point/{id}/charge : 포인트를 충전한다.
  • PATCH /point/{id}/use : 포인트를 사용한다.
  • GET /point/{id} : 포인트를 조회한다.
  • GET /point/{id}/histories : 포인트 내역을 조회한다.
  • 잔고가 부족할 경우, 포인트 사용은 실패해야 한다.
  • 동시에 여러 건의 포인트 충전, 이용 요청이 들어올 경우 순차적으로 처리되어야 한다. (동시성 고려)

제한사항

  • build.gradle은 수정하지 않는다 (추가적인 dependencies를 사용하지 않는다)
  • 초기에 주어진 DB 로직(UserPointTable, PointHistoryTable은 수정하지 않는다)

Additional... (추가적인 구현/고려 사항들)

  • Transaction이 적용되어 있지 않기 때문에 각 기능의 원자성(atomicity)이 보장되지 않는다.
    • ex. 포인트 충전(PointService.chargePoint()) 중 포인트 충전 내역 저장(PointHistoryRepository.save()) 기능에서 에러가 발생했을 때, 충전된 포인트를 rollback 해야 함.
  • 현재 단일 유저에 대한 동시성 제어만 진행하고 있기 때문에 동시에 여러 유저로부터 포인트 충전/사용 요청이 왔을 경우 PointHistoryTable에서 문제가 발생할 수 있음.
    • PointHistoryTablecursor를 동시에 조회함으로써 PK 역할을 하는 cursor가 중복되어 저장될 수 있음.
    • 다만, 이 부분은 DB 접근/구현 계층에서 고려해야 할 역할이라고 판단하였고, 이번 미션에서는 "database" package 코드를 수정하지 않는 것을 요구했으므로 무시하고 진행.
    • AtomicLong처럼 thread-safe data type을 쓴다던지, 실제 DBMS를 사용한다면 충분히 해결할 수 있고, 해당 계층에서 책임져야 할 역할이라고 생각하였음.

About

TDD로 개발하기

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages