나는 효과적인 자바 (확장 토론에서 항목 18로, 스켈 리턴 구현을 여기 ). 추상 클래스로는 정의 할 수없는 "갭을 메우기"위해 서브 클래스 메소드를 호출하는 2 개의 공용 메소드 methodA () 및 methodB ()를 제공하는 추상 클래스입니다.
먼저 구체적인 클래스를 만들고 단위 테스트를 작성하여 개발했습니다. 두 번째 클래스가 왔을 때, 나는 일반적인 행동을 추출하고 두 번째 클래스에서 "누락 간격"을 구현할 수 있었고 준비가되었습니다 (물론 두 번째 하위 클래스에 대한 단위 테스트가 만들어졌습니다).
시간이 흐르면서 지금은 4 개의 서브 클래스가 있는데, 각 서브 클래스는 구체적인 구현에 매우 특정한 3 개의 짧은 보호 된 메소드를 구현하는 반면 골격 구현은 모든 일반 작업을 수행합니다.
내 문제는 새로운 구현을 만들 때 테스트를 다시 작성한다는 것입니다.
- 서브 클래스는 주어진 필수 메소드를 호출합니까?
- 주어진 메소드에 주어진 주석이 있습니까?
- 방법 A에서 예상되는 결과를 얻습니까?
- 방법 B에서 예상되는 결과를 얻습니까?
이 접근 방식의 장점을 참조하십시오.
- 테스트를 통해 서브 클래스 요구 사항을 문서화합니다.
- 리팩토링에 문제가있는 경우 빠르게 실패 할 수 있습니다
- 서브 클래스를 전체적으로 그리고 공용 API를 통해 테스트하십시오 ( "methodA ()가 작동합니까?"및 "이 보호 된 메소드가 작동합니까?").
내가 가지고있는 문제는 새로운 서브 클래스에 대한 테스트가 기본적으로 쉬운 일이 없다는 것입니다. 테스트의 어설 션 부분을 확인하십시오. -일반적으로 서브 클래스에는 특정 테스트가 없습니다.
테스트가 서브 클래스 자체의 결과에 중점을두고 리팩토링으로부터 보호하는 방식이 마음에 들지만 테스트 구현이 "수동 작업"이되었다는 사실로 인해 내가 뭔가 잘못하고 있다고 생각합니다.
클래스 계층을 테스트 할 때이 문제가 일반적입니까? 어떻게 피할 수 있습니까?
추신 : 나는 골격 클래스를 테스트하는 것에 대해 생각했지만 테스트 할 수있는 추상 클래스의 모형을 만드는 것이 이상하게 보입니다. 그리고 서브 클래스에서 예상하지 않은 동작을 변경하는 추상 클래스의 리팩토링은 빠르지 않을 것이라고 생각합니다. 내 직감은 서브 클래스를 "전체적으로"테스트하는 것이 여기에서 선호되는 접근법이라고 말하지만, 내가 틀렸다고 말해주십시오. :)
추신 : 나는 구글과 주제에 관한 많은 질문을 발견했습니다. 그 중 하나는 이쪽 이 좋은 답변을 내 경우는 자신의 '숫자 1'이 될 것입니다, 나이젤 쏜에서을 그것은 좋을 것이지만, 지금은 리팩터링 할 수 없으므로이 문제로 살아야합니다. 리팩토링 할 수 있으면 각 하위 클래스를 전략으로 사용합니다. 괜찮지 만, 여전히 "주요 클래스"를 테스트하고 전략을 테스트 하겠지만 주 클래스와 전략의 통합을 방해하는 리팩터링은 눈치 채지 못할 것입니다.
추신 : 추상 클래스를 테스트하는 것이 "허용됩니다"라는 답변을 찾았습니다. 나는 이것이 수용 가능하다는 것에 동의하지만,이 경우 어떤 접근법이 선호되는지 알고 싶습니다. (여전히 단위 테스트로 시작하고 있습니다)