해결된 질문
작성
·
970
7
안녕하세요 강의 재밌게 듣고 있습니다 :D
이번 강의 중 테스트에 있어 DI의 장점을 제 나름의 언어로 재정의 해보았습니다.
의존성을 고립시켜 테스트 목적 객체가 아닌 다른 객체의 영향으로 실패할 수 있는 상황을 차단한다.
따라서 DI는 단위 테스트에 대한 신뢰성을 보장한다
라고 이해했습니다.
그런데 이런 생각을 하던 도중 그렇다면 소스코드가 테스트를 의식한 코드를 작성해야 하는 것 아닌가? 하는 생각도 듭니다.
예전에는 이게 싫어서 해당 객체를 상속받은 페이크 객체를 만들어서 테스트 코드에서 의존성을 밀어 넣는 식으로 작성했는데요,
다른 의견들도 찾아보니 소스코드의 안정성을 보장하기 위해 테스트에 의존한 코드를 짜야 한다, 테스트는 소스코드를 위해 존재하는데 소스코드가 테스트에 의존하는 건 자연스럽지 않다, 테스트하기 좋은 간단한 코드를 짜면 이러한 걱정할 필요가 없다 등 여러 의견들이 있는 것 같습니다.
따라서 이에 토비님 의견도 궁금하고 듣고 싶습니다 ㅎㅎ
감사합니다.
답변 1
9
애플리케이션 코드가 테스트 코드를 의식해야 한다거나 영향을 받아야 한다는 데는 저는 동의할 수는 없습니다. 애플리케이션 코드는 그 자체로 좋은 설계를 가지고 개발하면 됩니다.
그런데 왜 그런 얘기들이 나오냐면, 그건 테스트하기 안 좋거나 불편한 코드가 많이 만들어지기 때문입니다. 그래서 테스트하기 좋은 코드가 결국 좋은 코드이다, 이런 말을 하기도 하죠. 더 나아가서 테스트하기 편하도록 개발할 때 의식을 해야한다, 그런 얘기까지도 하는 듯합니다.
이건 반만 맞는 이야기인데요. 테스트를 작성하기가 불편하게 만들어진 코드는 안 좋은 코드일 가능성이 높습니다. 강한 결합으로 구현, 기술에 직접 의존하는 코드였거나, 응집도가 낮은 코드일테니까요. 하지만 테스트 하기 좋은 코드가 꼭 좋은 코드인 건 아닙니다. 그건 애플리케이션 코드의 설계 전반을 따져봐야하지요. 단지 테스트하기에 좋기만 하면 무조건 코드가 잘 설계되고 만들어진 것은 아니라는 겁니다. 그저 최소한의 조건은 통과했다고 볼 수있을 뿐이지요.
DI의 장점을 얘기할 때 단위 테스트 등을 편하게 작성할 수 있다는 점을 많이 얘기합니다. 예전에 애플리케이션을 테스트 하려면 전체를 빌드해서 서버에 배포하고 난 뒤에 수동 테스트로만 가능했던 시절에 비하면, DI로 코드의 의존관계가 잘 분리되어있는 경우엔, 런타임 의존관계 설정을 통해서 테스트를 쉽고 빠르게 할 수 있는 다양한 기법을 적용할 수 있습니다. 스프링이나 부트도 그런 지원을 매우 충실하게 하고 있고요.
하지만 DI의 장점은 단지 테스트하기 좋은 코드라는 것만은 아닙니다. 그건 일부이고요. 그보다 더 근본적으로 유연하게 확장할 수 있도록 잘 설계된 코드를 만드는데 있습니다.
아마 처음엔 코드를 작성하다가, 아 이렇게 만들면 테스트하기 힘들겠구나, 그래서 코드 설계를 다시 검토하는 경험을 하실 수 있습니다. 그게 나쁘지는 않습니다. 앞에서 설명했 듯이 테스트하기 나쁜 코드는 나쁜 코드일 가능성이 높다는 신호가 되니까요. 하지만 애플리케이션을 잘 설계하는 경험이 쌓이고, DI를 잘 활용할 수 있게 되면 더 이상 테스트를 의식하지 않고도 좋은 코드를 작성하실 수 있게 될 겁니다.
친절한 설명 너무 감사드립니다! 핵심은 DI를 잘 활용하게 되어 설계 실력이 늘면 테스트도 이에 따라 작성하게 된다는 이야기군요 DI를 잘 사용하면 테스트 작성이 용이한 것이 되어야지 테스트를 용이하게 작성하기 위해 DI를 이용하는 것은 올바르지 않은 패턴으로 이어질 수 있다는 것이고요.