Clean Code 15장 - JUnit 들여다보기
JUnit 프레임워크
- JUnit에 대해서는 이미 충분히 알아보았다.
- 클린코드에서 몇번의 리팩토링을 거쳐 완성된 ComparisonCompactor.java를 한번 살펴보고 지나가자
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| import junit.framework.Assert;
public class ComparisonCompactor { 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 prefixLength; private int suffixLength;
public ComparisonCompactor(int contextLength, String expected, String actual) { this.contextLength = contextLength; this.expected = expected; this.actual = actual; }
public String formatCompactedComparison(String message) { String compactExpected = expected; String compactActual = actual; if (shouldBeCompacted()) { findCommonPrefixAndSuffix(); compactExpected = compact(expected); compactActual = compact(actual); } return Assert.format(message, compactExpected, compactActual); }
private boolean shouldBeCompacted() { return !shouldNotBeCompacted(); }
private boolean shouldNotBeCompacted() { return expected == null || actual == null || expected.equals(actual); }
private void findCommonPrefixAndSuffix() { findCommonPrefix(); suffixLength = 0;
for (; !suffixOverlapsPrefix(); suffixLength++) { if (charFromEnd(expected, suffixLength) != charFromEnd(actual, suffixLength)) break; } }
private char charFromEnd(String s, int i) { return s.charAt(s.length() - i - 1); }
private boolean suffixOverlapsPrefix() { return actual.length() - suffixLength <= prefixLength || expected.length() - suffixLength <= prefixLength; }
private void findCommonPrefix() { prefixLength = 0; int end = Math.min(expected.length(), actual.length()); for (; prefixLength < end; prefixLength++) if (expected.charAt(prefixLength) != actual.charAt(prefixLength)) break; }
private String compact(String s) { return new StringBuilder() .append(startingEllipsis()) .append(startingContext()) .append(DELTA_START) .append(delta(s)) .append(DELTA_END) .append(endingContext()) .append(endingEllipsis()) .toString(); }
private String startingEllipsis() { return prefixLength > contextLength ? ELLIPSIS : ""; }
private String startingContext() { int contextStart = Math.max(0, prefixLength - contextLength); int contextEnd = prefixLength; return expected.substring(contextStart, contextEnd); }
private String delta(String s) { int deltaStart = prefixLength; int deltaEnd = s.length() - suffixLength; return s.substring(deltaStart, deltaEnd); }
private String endingContext() { int contextStart = expected.length() - suffixLength; int contextEnd = Math.min(contextStart + contextLength, expected.length()); return expected.substring(contextStart, contextEnd); }
private String endingEllipsis() { return (suffixLength > contextLength ? ELLIPSIS : ""); }
}
|
- 클린코드에서 보이스카우트 규칙을 얘기하니 나도 좀 더 고쳐야겠다.
결론
- JUnit을 잘못 만들었다는게 아니다.
- 세상에 개선이 불필요한 모듈은 없다.
- 코드를 처음보다 조금 더 깨끗하게 만드는 책임은 우리 모두에게 있다.