# 가치 있는 단위 테스트를 위한 리팩토링

{% hint style="info" %}
좋지 않은 테스트를 작성하는 것보다는 테스트를 작성하지 않는 것이 더 좋다. 가치가 별로 없는 테스트는 좋지 않은 테스트이다.
{% endhint %}

## 리팩토링할 코드 식별하기

* 코드 **복잡도와 도메인 유의성**
  * **코드 복잡도** → 코드 내 분기(결정) 지점 수로 정의하고, 클수록 복잡도가 더 높아짐 (복잡한 코드는 보통 도메인 유의성이 높다.)
  * **도메인 유의성** → 도메인에 대해 얼마나 의미있는지를 나타냄. 즉, 최종 사용자의 목표와 직접적인 연관성이 있으면 유의성이 높다.
* 코드 내의 **협력자 수**
  * **프로세스 외부 의존성** → 외부 애플리케이션 또는 서비스와 상호작용하는 경우
  * **가변 의존성**  → 의존하는 객체가 시간에 따라 다른 요소로 변경되는 경우
  * 협력자가 많은 테스트는 의존성을 목킹하고 준비하는 코드가 필요하므로 테스트 크기가 늘어나 유지보수성이 낮아진다.

### 코드의 네 가지 유형

* **도메인 모델과 알고리즘**&#x20;
  * 협력자가 거의 없으며, 도메인 모델이거나 도메인과 관련 없지만 복잡한 알고리즘을 가진 코드
  * 단위 테스트를 수행하기 가장 적절한 유형, 복잡하거나 중요한 로직은 회귀방지가 뛰어나기 때문에 가치가 있다.
  * 도메인 유의성이 높은 코드는 프로세스 외부 협력자를 사용해선 안된다.
* **간단한 코드**&#x20;
  * 간단한 코드는 대부분 협력자가 없고 복잡도와 도메인 유의성이 거의 없는 편이라 테스트를 작성할 필요가 없다.
* **컨트롤러**
  * 비즈니스에 중요한 작업을 하지 않고, 분리된 도메인 로직과 외부 의존성을 컨트롤하는 부분
  * 통합 테스트로 간단히 테스트
* **지나치게 복잡한 코드**&#x20;
  * 테스트가 필요하지만 가장 작성하기 어려운 유형 (협력자가 많고, 복잡성이 높은 유형)
  * 좋지 않은 테스트를 작성하는 것보다 전혀 작성하지 않는 편이 낫다.&#x20;
  * 복잡한 코드와 컨트롤러로 분리하는 리팩토링이 필요하다.

{% hint style="info" %}
코드에 중요한 로직이 포함되있거나 복잡성이 증가할수록 반비례해서 협력자 수가 적어져야 한다.
{% endhint %}

## 지나치게 복잡한 코드 리팩토링하기

> 지나치게 복잡한 코드를 도메인 모델과 알고리즘과 컨트롤러 두 부분으로 쪼개보자.

### 험블 객체 패턴

> 테스트하기 쉬운 비즈니스 로직과 테스트하기 어려운 프로세스 외부 의존성을 분리하는 디자인 패턴
>
> 테스트하기 어려운 부분이 험블 객체(컨트롤러)가 된다.&#x20;

* 헥사고날 아키텍처, 함수형 아키텍처는 험블 객체 패턴을 구현한다.
* 지나치게 복잡한 코드에서 로직을 추출해 코드를 테스트할 필요가 없도록 만든다.
* 험블 객체 패턴은 단일 책임 원칙을 따라 비즈니스 로직과 오케스트레이션으로 분리한다.
  * 코드의 깊이와 너비 관점으로 책임을 나눌 수 있다. 깊을수록 복잡하고 넓을수록 협력자가 많다. 둘 다는 없다.
* 코드가 복잡하고 중요한 경우 도메인 모델과 알고리즘 유형으로, 협력자와 상호작용하는 코드를 컨트롤러 유형으로 옮긴다.

{% hint style="info" %}
**오케스트레이션**이란 애플리케이션을 관리하고 실행하는 컨트롤러의 역할을 의미한다.
{% endhint %}

## 단계 별로 리팩토링하기

### 1. 암시적 의존성을 명시적으로 만들기

* 관심사를 분리해서 의존성을 명시적으로 주입하는 형태로 리팩토링한다.
* 테스트에서 의존성을 목으로 처리할 수 있게 된다.
* 단, 도메인 모델은 직접적이든, 간접적이든 프로세스 외부 협력자에게 의존하지 않는 것이 좋다.

### 2. 애플리케이션 서비스 계층 도입

* 도메인 모델은 일반적으로 내부 의존성에만 의존해야하기 때문에 외부 시스템과 직접 상호작용하는 것을 피해야 한다.
* 도메인 모델이 외부 시스템과 직접 상호작용하는 문제를 해결하기 위해 험블 객체(컨트롤러)로 책임을 옮겨야 한다.&#x20;
* 애플리케이션 서비스 계층의 역할은 복잡도나 도메인 유의성과 관련된 로직이 아니라 오케스트레이션만 해당된다.
