이렇게 해도 Error 객체가 생성되는지 확인하는 테스트는 통과하겠지만, 그럼 이 함수는 깨진 코드가 되어 버린다. 추가한 테스트가 그렇게 무관하지 않다는 사실을 이제 알겠는가? 누가 실제로 일부러 이렇게 바꿀 일은 많지 않겠지만, 사고는 늘 우연히 터진다.
정말 그렇다. 이 코드는 테스트할 수는 있지만 까다롭다. 테스트할 조건이 엄청 다양하게 조합될 수 있고 이들을 죄다 보완하는 건 불가능에 가깝다. 애플리케이션 코드를 전부 이렇게 작성하면 단위 테스트 영역이 적합하지 않다고 확실히 말할 수 있다.
그럼, 세 관심사를 validateAndRegisterUser 함수에 다 맡기지 말고 별개의 객체로 각 관심사를 추출하여 단일 책임을 부여하면 어떨까? 이렇게 만든 독립적인 객체는 각자 완전한 테스트 꾸러미를 갖게 될 테고 validateAndRegisterUser 코드는 이런 모습을 갖추게 될 것이다.
var Users = Users | | {}; Users.registration = function(userValidator, userRegister, userDisplay) { return { validateAndRegisterUser: function validateAndDisplayUser(user) { if (!userValidator.userIsValid(user)) { throw new Error("사용자 인증이 실패했습니다."); } userRegister.registerUser(user); userDisplay.showRegistrationThankYou(user); } }; };
새로 고친 registration 모듈은 user 검증, 등록, 화면 표시를 담당하는 개별 객체 인스턴스(instance)를 의존성 주입으로 제공한다. 그리고 validateAndRegisterUser는 다른 관심사에 직접 영향을 미쳤던 코드 대신 주입된 객체를 사용한다.