- 우리는 가장 의미있는 테스트(general case)를 제일 먼저 떠올린다.
- 하지만 그런 테스트는 구현이 복잡하고, 그런 기능을 제일 먼저 구현하면 예외적인 경우들이 누락되는 현상이 발생하기 쉽다.
- tdd에서는 functional decomposition을 통해서 가장 단순한 테스트(special case)부터 추가해 가면서 최종적으로 general case에 도달하기 위한 stair step tests 목록을 작성하게 됨
- 절차
- most simple and degenerate(special)에서 시작
- null, empty, 0, boundary, simple stuff 등과 같은 special case
- most simple and degenerate(special)에서 시작
- 다음 단계로 interesting 하지만 조금 덜 degenerate한 테스트 케이스(단일
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public void updateName(Long id, String newName) { | |
| User user = userRepository.findById(id).orElseThrow(); // 그냥 POJO | |
| user.setName(newName); | |
| userRepository.save(user); // 명시적. 호출 안 하면 아무 일도 없다. | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| static class OrderRepositoryInMemory implements OrderRepository { | |
| private final Map<Long, Order> orders = new ConcurrentHashMap<>(); | |
| private final AtomicLong idGenerator = new AtomicLong(1); | |
| public Order save(Order order) { | |
| if (order.getId() == null) { | |
| Long id = idGenerator.getAndIncrement(); | |
| Order savedOrder = new Order(id, order.getItems()); | |
| orders.put(id, savedOrder); | |
| return savedOrder; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 순수 인터페이스 (도메인 계층) | |
| public interface OrderRepository { | |
| Order save(Order order); | |
| Optional<Order> findById(Long id); | |
| } | |
| // JPA 구현체 (인프라 계층) | |
| @Repository | |
| public class JpaOrderRepository implements OrderRepository { | |
| private final OrderJpaRepository jpaRepository; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 도메인 서비스가 JpaRepository에 직접 의존 | |
| @Service public class OrderService { | |
| private final OrderRepository orderRepository; // JpaRepository 상속 | |
| public void createOrder(OrderRequest request) { | |
| // 도메인 로직이 JPA에 종속됨 | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @Transactional | |
| public void updateName(Long id, String newName) { | |
| User user = userRepository.findById(id).orElseThrow(); | |
| user.setName(newName); | |
| // 여기서 마법이 일어난다. save() 없이도 DB가 업데이트된다. | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class Divider { | |
| public int divide(int dividend, int divisor) { | |
| if (divisor == null) { | |
| throw new IllegalArgumentException("divisor must not be null"); | |
| } | |
| if (dividend == null) { | |
| throw new IllegalArgumentException("dividend must not be null"); | |
| } | |
| if (divisor == 0) { | |
| throw new IllegalArgumentException("divisor must not be 0"); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class Divider { | |
| public int divide(int dividend, int divisor) { | |
| if (divisor != null) { | |
| if(dividend != null) { | |
| if (divisor != 0) { | |
| return dividend / divisor; | |
| } else { | |
| throw new IllegalArgumentException("divisor must not be 0"); | |
| } | |
| } else { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class Divider { | |
| public int divide(int dividend, int divisor) { | |
| return dividend / divisor; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { calc, search } from '@/pages/goodsList/search'; | |
| describe('search api', () => { | |
| it('search api를 호출한다.', async () => { | |
| const { data } = await search({ keyword: 'blackpink' }); | |
| // console.log(data); | |
| expect(data).toMatchSnapshot(); | |
| }); | |
| }); |
NewerOlder