13
Clean Code Ch.15 JUnit chois79 1293월요일

Clean code ch15

Embed Size (px)

Citation preview

Page 1: Clean code ch15

Clean CodeCh.15 JUnit

chois79

12년 9월 3일 월요일

Page 2: Clean code ch15

JUnit 프레임워크

• JUnit 소개

• Java 언어용 테스트 프레임워크

• 저자: 켄트벡, 에릭감마 등

• v3.x 구조

• 모든 테스트 클래스는 testCase를 상속 받음

• 테스트 메소드의 이름은 test로 시작해야 함

• But, 이 장에서는 JUnit에서 가져온 예제 코드 ComparisonCompactor.java 를 평가

import junit.framework.TestCase;

public class ComparisoncompactorTest extends TestCase{ public void testMessage() { String failure = new ComparisonCompactor(0, "b", "c").compact("a"); assertTrue("a expected:<[b]> but was:<[c]>".equals(failure)); }}

12년 9월 3일 월요일

Page 3: Clean code ch15

ComparisonCompactor Class

• 두 문자열을 받아 차이를 반환

• ex) ABCDE, ABXDE => ...B[X]D...public class ComparisonCompactor { private static final String ELLIPSIS = "..."; private static final String DELTA_END = "]"; private static final String DELTA_START= "["; private int fContextLength; private String fExpected; private String fActual; private int fPrefix; private int fSuffix; public ComparisonCompactor(int contextLength, String expected, String actual) { fContextLength = contextLength; fExpected = expected; fActual = actual; } public String compact(String message) { if(fExpected == null || fActual == null || areStringEqual()) return assertFormat(message, fExpected, fActual); findCommonPrefix(); findCommonSuffix(); String expected = compactString(fExpected); String actual = compactString(fActual); return assertFormat(message, expected, actual); }

12년 9월 3일 월요일

Page 4: Clean code ch15

ComparisonCompactor Class

private String compactString(String source) { String result = DELTA_START + source.substring(fPrefix, source.length() - fSuffix + 1) + DELTA_END; if(fPrefix > 0) { result = computeCommonPrefix() + result; } if(fSuffix > 0) { result = result + computeCommonSuffix(); } return result; }

private void findCommonSuffix() { int expectedSuffix = fExpected.length() - 1; int actualSuffix = fActual.length() - 1; for(; actualSuffix >= fPrefix && expectedSuffix >= fPrefix; actualSuffix--, expectedSuffix--) { if(fExpected.charAt(expectedSuffix) != fActual.charAt(actualSuffix)) break; } fSuffix = fExpected.length() - expectedSuffix; }

private void findCommonPrefix() { fPrefix = 0; int end = Math.min(fExpected.length(), fActual.length()); for(; fPrefix < end; fPrefix++) { if(fExpected.charAt(fPrefix) != fActual.charAt(fPrefix)) break; } }

12년 9월 3일 월요일

Page 5: Clean code ch15

ComparisonCompactor Class

private String computeCommonPrefix() { return (fPrefix > fContextLength? ELLIPSIS: "") + fExpected.substring(Math.max(0, fPrefix - fContextLength), fPrefix); }

private String computeCommonSuffix() { int end = Math.min(fExpected.length() - fSuffix + 1 + fContextLength, fExpected.length()); return fExpected.substring(fExpected.length() - fSuffix + 1, end) + (fExpected.length() - fSuffix + 1 < fExpected.length() - fContextLength? ELLIPSIS: ""); }

private boolean areStringEqual() { return fExpected.equals(fActual); }

private String assertFormat(String message, String fExpected, String fActual) { return message + “expected: <” + fExpected + “> but was: <” + fActual + “>”; }

}

12년 9월 3일 월요일

Page 6: Clean code ch15

Clean Code 적용

• 접두어 제거

• 접두어 제거로 인한 충돌

private static final String ELLIPSIS = "..."; private static final String DELTA_END = "]"; private static final String DELTA_START= "["; private int fContextLength; private String fExpected; private String fActual; private int fPrefix; private int fSuffix;

private static final String ELLIPSIS = "..."; private static final String DELTA_END = "]"; private static final String DELTA_START= "["; private int contextLength; private String expected; private String actual; private int prefix; private int suffix;

public String compact(String message) { if(expected == null || actual == null || areStringEqual()) return assertFormat(message, expected, actual); findCommonPrefix(); findCommonSuffix(); String expected = compactString(expected); String actual = compactString(actual); return assertFormat(message, expected, actual);}

public String compact(String message) { if(expected == null || actual == null || areStringEqual()) return assertFormat(message, expected, actual); findCommonPrefix(); findCommonSuffix(); String compactExpected = compactString(expected); String compactActual = compactString(actual); return assertFormat(message, compactExpected, compactActual);;}

12년 9월 3일 월요일

Page 7: Clean code ch15

Clean Code 적용

• 조건문 캡슐화

• 긍정 표현으로 변경

public String compact(String message) { if(expected == null || actual == null || areStringEqual()) return assertFormat(message, expected, actual); findCommonPrefix(); findCommonSuffix(); compactExpected = compactString(expected); compactActual = compactString(actual); return assertFormat(message, compactExpected, compactActual);}

public String compact(String message) { if(shouldNotCompact()) return assertFormat(message, expected, actual); findCommonPrefix(); findCommonSuffix(); compactExpected = compactString(expected); compactActual = compactString(actual); return assertFormat(message, compactExpected, compactActual);}private boolean shouldNotCompact() { return expected == null || actual == null || areStringEqual();}

public String compact(String message) { if(shouldNotCompact()) return assertFormat(message, expected, actual); findCommonPrefix(); findCommonSuffix(); compactExpected = compactString(expected); compactActual = compactString(actual); return assertFormat(message, compactExpected, compactActual);}private boolean shouldNotCompact() { return expected == null || actual == null || areStringEqual();}

public String compact(String message) { if(canBeCompacted()) { findCommonPrefix(); findCommonSuffix(); compactExpected = compactString(expected); compactActual = compactString(actual); return assertFormat(message, compactExpected, compactActual); } else { return assertFormat(message, expected, actual); }}private boolean canBeCompacted() { return expected != null && actual != null && areStringEqual();}

12년 9월 3일 월요일

Page 8: Clean code ch15

Clean Code 적용

• 함수의 의미를 명확하게 변경, Extract Method 적용public String compact(String message) {if(canBeCompacted()) { findCommonPrefix(); findCommonSuffix(); compactExpected = compactString(expected); compactActual = compactString(actual); return assertFormat(message, compactExpected, compactActual); } else { return assertFormat(message, expected, actual); }}

private String compactExpected;private String compactActual;

public String formatCompactedComparison(String message) { if(canBeCompacted()) { compactExpectedAndActual(); return assertFormat(message, compactExpected, compactActual); } return assertFormat(message, expected, actual);}

private void compactExpectedAndActual() { findCommonPrefix(); findCommonSuffix(); compactExpected = compactString(expected); compactActual = compactString(actual);}

12년 9월 3일 월요일

Page 9: Clean code ch15

Clean Code 적용

• 함수 내부의 사용 방식 통일private void compactExpectedAndActual() { findCommonPrefix(); findCommonSuffix(); compactExpected = compactString(expected); compactActual = compactString(actual);}

private void findCommonPrefix() { prefix = 0; int end = Math.min(expected.length(), actual.length()); for(; prefix < end; prefix++) { if(expected.charAt(prefix) != actual.charAt(prefix)) break; }}

private void findCommonSuffix() { int expectedSuffix = expected.length() - 1; int actualSuffix = actual.length() - 1; for(; actualSuffix >= prefix && expectedSuffix >= prefix; actualSuffix--, expectedSuffix--) { if( expected.charAt(expectedSuffix) != actual.charAt(actualSuffix)) break; } suffix = expected.length() - expectedSuffix;}

private void compactExpectedAndActual() { prefixIndex = findCommonPrefix(); suffixIndex = findCommonSuffix(); compactExpected = compactString(expected); compactActual = compactString(actual);}

private int findCommonPrefix() { int prefixIndex = 0; int end = Math.min(expected.length(), actual.length()); for(; prefixIndex < end; prefixIndex ++) { if(expected.charAt(prefixIndex) != actual.charAt(prefixIndex)) break; } return prefixIndex;}

private int findCommonSuffix() { int expectedSuffix = expected.length() - 1; int actualSuffix = actual.length() - 1; for(; actualSuffix >= prefixIndex && expectedSuffix >= prefixIndex; actualSuffix--, expectedSuffix--) { if( expected.charAt(expectedSuffix) != actual.charAt(actualSuffix)) break; } return expected.length() - expectedSuffix;}

12년 9월 3일 월요일

Page 10: Clean code ch15

Clean Code 적용

• 시간 결합 제거private void compactExpectedAndActual() { prefixIndex = findCommonPrefix(); suffixIndex = findCommonSuffix(); compactExpected = compactString(expected); compactActual = compactString(actual);}

private int findCommonSuffix() { int expectedSuffix = expected.length() - 1; int actualSuffix = actual.length() - 1; for(; actualSuffix >= prefixIndex && expectedSuffix >= prefixIndex; actualSuffix--, expectedSuffix--) { if( expected.charAt(expectedSuffix) != actual.charAt(actualSuffix)) break; } return expected.length() - expectedSuffix;}

private void compactExpectedAndActual() { prefixIndex = findCommonPrefix(); suffixIndex = findCommonSuffix(prefixIndex); compactExpected = compactString(expected); compactActual = compactString(actual);}

private int findCommonSuffix(int prefixIndex) { int expectedSuffix = expected.length() - 1; int actualSuffix = actual.length() - 1; for(; actualSuffix >= prefixIndex && expectedSuffix >= prefixIndex; actualSuffix--, expectedSuffix--) { if( expected.charAt(expectedSuffix) != actual.charAt(actualSuffix)) break; } return expected.length() - expectedSuffix;}

적절하지 못하다

12년 9월 3일 월요일

Page 11: Clean code ch15

Clean Code 적용

• 시간 결합 제거 ver2private void compactExpectedAndActual() { prefixIndex = findCommonPrefix(); suffixIndex = findCommonSuffix(prefixIndex); compactExpected = compactString(expected); compactActual = compactString(actual);}

private int findCommonSuffix(int prefixIndex) { int expectedSuffix = expected.length() - 1; int actualSuffix = actual.length() - 1; for(; actualSuffix >= prefixIndex && expectedSuffix >= prefixIndex; actualSuffix--, expectedSuffix--) { if( expected.charAt(expectedSuffix) != actual.charAt(actualSuffix)) break; } return expected.length() - expectedSuffix;}

private void compactExpectedAndActual() { findCommonPrefixAndSuffix(); compactExpected = compactString(expected); compactActual = compactString(actual);}

private void findCommonPrefixAndSuffix() { findCommonPrefix(); int expectedSuffix = expected.length() - 1; int actualSuffix = actual.length() - 1; for(; actualSuffix >= prefixIndex && expectedSuffix >= prefixIndex; actualSuffix--, expectedSuffix--) { if( expected.charAt(expectedSuffix) != actual.charAt(actualSuffix)) break; } return expected.length() - expectedSuffix;}

private void findCommonPrefix() { prefixIndex = 0; int end = Math.min(expected.length(), actual.length()); for(; prefix < end; prefix++) { if(expected.charAt(prefix) != actual.charAt(prefix)) break; }}

시간 결합을하나의 함수에 표현

12년 9월 3일 월요일

Page 12: Clean code ch15

Clean Code 적용

• 지저분해진 findCommonPrefixAndSuffix를 개선

private void findCommonPrefixAndSuffix() { findCommonPrefix(); int expectedSuffix = expected.length() - 1; int actualSuffix = actual.length() - 1; for(; actualSuffix >= prefixIndex && expectedSuffix >= prefixIndex; actualSuffix--, expectedSuffix--) { if( expected.charAt(expectedSuffix) != actual.charAt(actualSuffix)) break; } return expected.length() - expectedSuffix;}

private void findCommonPrefixAndSuffix() { findCommonPrefix(); int suffixLength = 1; for(; !suffixOverlapsPerfix(suffixLength); suffixLength++) { if( charFromEnd(expected, suffixLength) != charFromEnd(actual, suffixLength)) break; } suffixIndex = suffixLength}

private char charFromEnd(String s, int i) { return s.charAt(s.length() - i);}

private boolean suffixOverlapsPerfix(int suffixLength) { return actual.length() - suffixLength < prefixLength || expected.length() - suffixLength < prefixLength;}

suffixIndex가 실제로는접미어의 길이

12년 9월 3일 월요일

Page 13: Clean code ch15

Clean Code 적용

• suffixIndex를 suffixLength로 변경

• suffixLength로 인한 이슈 발생 (suffixLength > 0)

private int suffixLength = 0;private String compactString(String source) { String result = DELTA_START + source.substring( prefixLength, source.length() - suffixLength ) + DELTA_END; if(prefixLength > 0) { result = computeCommonPrefix() + result; } if(suffixLength > 0) { result = result + computeCommonSuffix(); } return result;}

private String compactString(String source) { String result = DELTA_START + source.substring( prefixIndex, source.length() - suffixIndex + 1 ) + DELTA_END; if(prefixIndex > 0) { result = computeCommonPrefix() + result; } if(suffixIndex > 0) { result = result + computeCommonSuffix(); } return result;}

private int suffixLength = 0;private String compactString(String source) { String result = DELTA_START + source.substring( prefixLength, source.length() - suffixLength ) + DELTA_END; if(prefixLength > 0) { result = computeCommonPrefix() + result; } if(suffixLength > 0) { result = result + computeCommonSuffix(); } return result;}

private String compactString(String source) {

return computeCommonPrefix() + DELTA_START + source.subString source.substring(prefixLength, source.length() - suffixLength ) + DELTA_END + computeCommonSuffix();}

12년 9월 3일 월요일