본문 바로가기
책/Clean Code

[Clean Code] 15장 JUnit 들여다 보기

by 오오오니 2025. 3. 17.

15 JUnit 들여다 보기

2024년 3월 18일 오후 4:34
비어 있음
JUnit은 자바 프레임 워크 중에 가장 유명하다. 이 장에서는 JUnit 프레임워크에서 가져온 코드를 평가한다.

JUnit 프레임 워크

우리가 살펴볼 모듈은 문자열 비교 오류를 파악할 때 유용한 코드인 ComparisonCompactor 모듈
ComparisonCompactor 모듈 코드
코드 커버리지 100 %
저자들이 모듈을 좋은 상태로 남겨두었지만 보이스카우트 규칙에 따르면 더 깨끗하게 해놓고 떠나야 한다.

개선

조건문 캡슐화

의도를 명확히 표현하려면 조건문을 캡슐화해야 한다.
복사
// Before if (expected == null || actual == null || areStringsEqual()) { return Assert.format(message, expected, actual); } // After if (shouldNotCompact()) { return Assert.format(message, expected, actual); } private boolean shouldNotCompact() { return expected == null || actual == null || areStringsEqual(); }

변수명을 명확하게 변경

이름은 명확하게 붙인다.
복사
// Before String expected = compactString(fExpected); String actual = compactString(fActual); // After String compactExpected = compactString(expected); String compactActual = compactString(actual);

부정문을 긍정문으로 변경

부정문은 긍정문보다 이해하기 더 어렵다. 긍정으로 만들어 조건문을 반전한다.
복사
// Before if (shouldNotCompact()) { return Assert.format(message, expected, actual); } else { } private boolean shouldNotCompact() { return expected == null || actual == null || areStringsEqual(); } // After if (canBeCompacted()) { } else { return Assert.format(message, expected, actual); } private boolean canBeCompacted() { return expected != null && actual != null && areStringsEqual(); }

적절한 함수이름 적용

compact라는 이름을 붙이면 오류 점검이라는부가 단계가 숨겨진다.
함수는 단순히 압축된 문자열이 아니라 형식이 갖춰진 문자열을 반환한다.
복사
// Before public String compact(String message) { } // After public String formatCompactedComparison(String message) { }

함수 분리

예상 문자열과 실제 문자열을 진짜 압축하는 부분을 빼내기
형식을 맞추는 작업은 formatCompactedComparison이 한다.
compactExpected, compactActual이 멤버 변수로 승격
복사
private String compactExpected; private String compactActual; public String formatCompactedComparison(String message) { if (canBeCompacted()) { compactExpectedAndActual(); return Assert.format(message, compactExpected, compactActual); } else { return Assert.format(message, expected, actual); } } private void compactExpectedAndActual() { // 변수 반환 x findCommonPrefix(); findCommonSuffix(); //변수 반환 o compactExpected = compactString(expected); compactActual = compactString(actual); }

일관적인 함수 사용방식 적용

위의 코드는 변수 반환에 있어서 사용방식이 일관적이지 못하다.
접두어 값과 접미어 값을 반환하게 수정
멤버 변수 이름도 바꿨다 prefix → prefixIndex
복사
// Before private void compactExpectedAndActual() { findCommonPrefix(); findCommonSuffix(); compactExpected = compactString(expected); compactActual = compactString(actual); } // After private void compactExpectedAndActual() { prefixlndex = findCommonPrefix(); suffixlndex = findCommonSuffix(); compactExpected = compactString(expected); compactActual = compactString(actual);

숨겨진 시간적인 결합

findCommonSuffix는 findCommonPrefix가 prefixIndex를 계산한다는 사실에 의존한다.
복사
//Before private void compactExpectedAndActual(} { prefixIndex = findCommonPrefix(}; suffixIndex = findCommonSuffix(prefixlndex); compactExpected = compactString(expected}; compactActual = compactString(actual}; } //After private void compatExpectedAndActual() { findCommonPrefixAndSuffix(); compactExpected = compactString(expected); compactActual = compactString(actual); } private void findCommonPrefixAndSuffix() { findCommonPrefix(); // 처리 로직 }

적절하지 못한 이름

suffixIndex가 실제로는 접미어 길이이다
suffixIndex → suffixLengh

' > Clean Code' 카테고리의 다른 글

[Clean Code] 17장 냄새와 휴리스틱  (1) 2025.03.17
[Clean Code] 13장 동시성  (0) 2025.03.17
[Clean Code] 11장 시스템  (0) 2025.03.17
[Clean Code] 9장 단위 테스트  (0) 2025.03.17
[Clean Code] 7 장 오류 처리  (0) 2025.03.17