////
Search
Duplicate

Chapter 9. 뚝딱! 테스트 하네스에 클래스 제대로 넣기

클래스를 테스트 하네스에 넣는 작업은 어려운 일이다. 다음은 가장 일반적으로 직면하는 네 가지 문제점이다.
1.
클래스의 객체를 쉽게 생성할 수 없다.
2.
클래스를 포함하는 테스트 하네스를 쉽게 빌드할 수 없다.
3.
반드시 사용해야 하는 생성자가 부작용을 일으킨다.
4.
생성자의 내부에서 상당량의 처리가 일어나며, 그 내용을 알아내야만 한다.
이번 장에서는 다양한 언어와 예제를 통해 이 문제점들을 짚어본다. 이를 통해 의존 관계 기법에 익숙해지고 특정 상황에 적합한 기법을 검토할 수 있게 될 것이다.

성가신 매개변수

테스트 하네스에서 객체를 생성하는 가장 좋은 접근 방식은 일단 해보는 것이다. 이를 통해 객체 생성이 가능할지, 그리고 그것이 쉬운지 어려운지 분석하는 것이다.
여기서 성가신 매개변수들이란 객체를 생성하기 위한 매개변수 중, 우리 시스템 외부에 의존성을 가지는 것들이다. 이들은 대체로 제어가 어렵다.
이런 경우, 인터페이스 추출 기법을 사용해 해당 매개변수를 대체할 수 있다. 가짜 객체를 만들어 생성자에 제공하는 방법이다.
테스트 하네스에서만 사용되는 테스트 대역은 제품 코드에 포함되지 않으므로 제품 코드의 규칙을 적용시킬 필요가 없다.
내부 객체에 접근하지 못하게 한다던지, 메소드를 과도하게 공개하는 등 캡슐화를 철저히 지킬 필요는 없다.

숨겨진 의존 관계

이 클래스의 생성자를 호출했더니 문제가 생기는 경우가 있다.
이런 문제를 생기게 만드는 장애물 중 가장 흔한 것이 숨겨진 의존 관계다.
이는 생성자를 처리할 때, 테스트 하네스 내에서 쉽게 접근할 수 없는 자원을 사용하는 경우 나타나기 쉽다.
이를 위해 사용할 수 있는 기법 중 하나가 생성자 매개변수화 기법이다. 이 기법을 사용해 생성자 내부의 의존 관계를 밖으로 들어낼 수 있다.
public class Human { public Human() { this.heart = new MechanicalHeart(); }; }
Java
복사
public class Human { public Human(Heart heart) { this.heart = heart; }; }
Java
복사
get 메소드 추출과 재정의, 팩토리 메소드 추출과 재정의, 인스턴스 변수 대체 등의 기법도 사용할 수 있지만 저자는 가급적 생성자 매개변수화 기법을 서호한다.

복잡한 생성자

만약, 생성자 내부에서 많은 수의 객체가 생성되거나 많은 수의 전역 변수에 접근하는 경우, 생성자의 매개변수가 지나치게 많아질 수 있다.
심지어는, 생성자의 매개변수들이 서로의 생성을 위해 사용되는 경우도 있다.
이 과정에서 팩토리 메소드 추출과 재정의 기법을 생성자 코드에 적용시켜 볼 수 있다.
또 다른 선택지로 인스턴스 변수 대체 기법을 제안하는데, 이는 set 메소드를 노출시켜 객체를 생성 후 인스턴스의 속성을 변경할 수 있도록 하는 것이다. 이는 자원 관리에 문제가 있을 수 있어 저자도 선호하지 않는 방법이다.

까다로운 전역 의존 관계

테스트 프레임워크에서 클래스 생성 및 사용을 어렵게 만드는 다양한 의존 관계 중 가장 까다로운 것이 전역 변수의 사용이다.
이런 전역 변수들의 의존 관계를 끊어내는 기법은 다양하나 인터페이스 추출 기법으로도 충분할 것 같다.
저자는 여기서 애플리케이션의 책임들을 분리하기 위해 노력을 기울인다면 전역 변수에 대한 의존 관계를 점진적으로 지역화할 수 있다고 한다.

공포스러운 인클루드 의존 관계

C++의 구조 상, 인스턴스 생성을 위해 헤더 의존 관계를 해결하기 어렵다는 문제다.

양파껍질 매개변수

앞선 복잡한 생성자와 유사한 문제인 것 같다.
테스트 시, 불필요한 것은 널 전달 기법을 사용하거나 인터페이스 추출 기법을 사용하여 테스트 대역을 사용하여 의존 관계를 제거하라는 내용이었다.

별명을 갖는 매개변수

앞서 살펴봤듯 생성자의 매개변수가 문제가 되는 경우, 대체로 인터페이스 추출 기법을 사용해 문제를 우회할 수 있다.
복잡한 의존 관계를 가지는 생성자의 매개변수에는 실용적인 해결책이 되지 못한다.
이때, 인터페이스들로만 이뤄진 의존 관계 계층 구조를 생성하고 대입할 수 있는데, 이는 상당량의 작업을 수반하며 코드가 복잡해지곤 한다.
안 좋은 방법이라는 의미가 아니다. 이런 길도 있다라는 의미다.
인터페이스 추출 기법은 매개변수 의존 관계 제거 기법의 하나일 뿐이다. 가끔은 왜 의존 관계가 나쁜지 생각해보는 것도 좋다.
또는 서브클래스화와 메소드 재정의 기법의 사용을 고려해볼만 하다.