<aside> 💡 뭔가 잘못된 가능성은 늘 존재한다
</aside>
1 Try-Catch-Finally 부터 작성하라
먼저 강제로 예외를 일으키는 테스트 케이스를 작성한 후 테스트를 통과하는 코드를 작성하자
// 파일이 없으면 예외를 던지는 지 알아보는 단위 테스트
@Test(expected = StorageException.class)
public void retrieveSectionShouldThrowOnInvalidFileName() {
sectionStore.retrieveSection("invalid-file");
}
// 단위 테스트에 맞춘 코드
public List<RecordGrip> retrieveSection(String sectionName) {
// 실제로 구현할 때까지 비어 있는 더미 반환
return new ArrayList<RecordedGrip>();
}
// 그러나 코드가 예외를 던지지 않아 단위 테스트가 실패했다.
// 잘못된 파일 접근을 시도하도록 코드를 구성하자
public List<RecordGrip> retrieveSection(String sectionName) {
// 실제로 구현할 때까지 비어 있는 더미 반환
try {
FileInputStream stream = new FileInputStream(sectionName);
} catch (Exception e) {
throw new StorageException("retrieval error", e)'
}
return new ArrayList<RecordedGrip>();
}
// 코드가 예외를 던지므로 테스트 성공
// 리팩토링을 통해 catch블록에서 예외 유형을 좁혀 실제로 FileInputStream 생성자가 던지는 FileNotFoundException을 잡아낸다
public List<RecordGrip> retrieveSection(String sectionName) {
// 실제로 구현할 때까지 비어 있는 더미 반환
try {
FileInputStream stream = new FileInputStream(sectionName);
stream.close();
} catch (FileNotFoundException e) {
throw new StorageException("retrieval error", e)'
}
return new ArrayList<RecordedGrip>();
}
2 예외에 의미를 제공하라
자바는 모든 예외에 호출 스택을 제공한다
오류 메세지에 정보를 담아 예외와 함께 던진다.
→ 실패한 연산 이름과 실패 유형을 언급한다
3 호출자를 고려해 예외 클래스를 정의하라
오류를 분류하는 방법(컴포터넌트, 유형 등)
→ 디바이스 실패, 네트워크 실패, 프로그래밍 오류 등