[TIL] 21.04.07.(Wed)
활동 요약
- PR 피드백 수신
- PR 피드백 고민 및 반영
JSON
디코딩 관련
- CustomJSONDecoder 타입으로 디코딩 방식 회귀
- CustomJSONDecoder 타입의 Decode 메서드 로직 변경 (제네릭 타입을 제네릭 메서드로)
- 에러 처리 로직 추가 (에러 타입)
- 테스트 메서드 로직 변경:
JSON
데이터 디코드 결과 검증 방식 변경
XCAssertNoThrow(_:)
활용 검증
- 코드 작성 스타일 관련
- 테스트 코드에서도 암시적 옵셔널 타입(
!
) 사용 지양. 일반 옵셔널(?
) 활용 후 throw error
- Result 타입 활용한 에러 처리 방식 학습. (부제: 야곰의 Pick은?)
Class Diagram
관련
- 자주 사용하는 프로토콜은 채택 사실만 확인할 수 있도록 Class Diagram에 표시
- 만국박람회 프로그램 Class Diagram 1차 수정본 작성
- 기타
- testExample() 메서드 관련 오해 해소
- PR 피드백 반영 후 추가 커밋 push
요약이 왜 이렇게 긴고..
활동 내용 상세
PR 피드백 수신
JSON
디코딩 관련- CustomJSONDecoder 타입으로 디코딩 방식 회귀
- CustomJSONDecoder 타입의 Decode 메서드 로직 변경 (제네릭 타입을 제네릭 메서드로)
- 에러 처리 로직 추가 (에러 타입)
- 테스트 메서드 로직 변경:
JSON
데이터 디코드 결과 검증 방식 변경XCAssertNoThrow(_:)
활용 검증
- 코드 작성 스타일 관련
- 테스트 코드에서도 암시적 옵셔널 타입(
!
) 사용 지양. 일반 옵셔널(?
) 활용 후throw error
- Result 타입 활용한 에러 처리 방식 학습. (부제: 야곰의 Pick은?)
- 테스트 코드에서도 암시적 옵셔널 타입(
Class Diagram
관련- 자주 사용하는 프로토콜은 채택 사실만 확인할 수 있도록 Class Diagram에 표시
- 만국박람회 프로그램 Class Diagram 1차 수정본 작성
- 기타
- testExample() 메서드 관련 오해 해소
요약이 왜 이렇게 긴고..
PR 피드백 수신
킹갓엠페러제너럴충무공마제스티 야곰 야멘!!! 우후!!!!
힘이 되는 피드백 감사합니다..! 💪
PR 피드백 고민 및 반영
JSON
디코딩 관련
CustomJSONDecoder 타입으로 디코딩 방식 회귀
CustomJSONDecoder 타입의 Decode 메서드 로직 변경 (제네릭 타입을 제네릭 메서드로)
에러 처리 로직 추가 (에러 타입)
어제 TIL에서도 언급했던 내용으로, JSON
데이터 디코딩 메서드를 가볍게 래핑하는 과정에서 프로토콜로 기능을 구현할지, 구조체나 클래스와 같은 인스턴스화가 가능한 메서드로 구현할지 고민했습니다. 그리고 오늘 코드 리뷰를 받아보니 인스턴스화가 가능한 타입으로 구현하는 것이 여러 타입에 유연하게 대응할 수 있어 더 나아보인다는 의견을 주셨습니다.
그리고 매 번 인스턴스를 생성할 때마다 타입을 정해주는 방식 보다 메서드를 사용할 때 디코딩할 타입을 지정하는 것이 편의성 측면에서 더 낫다고 생각하여 아래 코드와 같이 제네릭 타입을 제네릭 메서드로 변경했습니다. 아울러 기존 JSONDecoder
타입의 decode(_:from:)
메서드의 에러 처리를 호출하는 쪽에서 함께 담당하는 형식으로 변경하여 테스트를 수행할 때 새로 작성한 메서드에서 에러를 검출할 수 있게끔 만들었어요.
/// Decodable 프로토콜을 준수하는 타입에 대해 타입 이름과 파일 이름 입력만으로 JSON 디코딩을 도와주는 메서드를 제공하는 타입.
class CustomJSONDecoder {
/// 변환할 타입과 JSON 파일 이름을 전달인자로 받아 지정된 타입으로 디코딩 결과를 반환한다.
/// - 전달인자에 유효하지 않은 JSON 파일을 입력할 경우 `ExpoAppError.invalidJSONFile` 에러를 던진다.
/// - Parameter type: 변환할 타입. 모델 타입의 인스턴스를 원하면, `모델타입.self`로 작성한다.
/// - Parameter jsonFileName: JSON 파일 이름을 `String` 타입으로 작성한다.
public func decode<Decoded>(to type: Decoded.Type,
from jsonFileName: String) throws -> Decoded? where Decoded: Decodable {
var decodedResult: Decoded?
let jsonDecoder = JSONDecoder()
guard let jsonData: NSDataAsset = NSDataAsset(name: jsonFileName) else {
throw ExpoAppError.invalidJSONFile
}
decodedResult = try jsonDecoder.decode(Decoded.self, from: jsonData.data)
return decodedResult
}
}
테스트 메서드 로직 변경: JSON
데이터 디코드 결과 검증 방식 변경
XCAssertNoThrow(_:)
,XCAssertThrowsError(_:_:)
활용 검증
메서드를 수정했으니 테스트 방식도 변경해야겠죠? 이제 에러를 던지는 throwing function
으로 구현했으니 XCTAssertNoThrow(_:)
와 XCAssertThrowsError(_:_:)
를 활용할 수 있겠네요. 아래 코드 처럼요!
func test_customJSONDecoder_decode() {
let jsonDecoder = CustomJSONDecoder() // 이제 인스턴스는 한 번만 생성!
// 한 번의 인스턴스 생성으로 여러 가지 타입 디코딩이 가능!
XCTAssertNoThrow(try jsonDecoder.decode(to: ExpoIntroduction.self, from: "exposition_universelle_1900"))
XCTAssertNoThrow(try jsonDecoder.decode(to: [Artwork].self, from: "items"))
}
func test_customJSONDecoder_decode_withInvalidJSONFile() {
let jsonDecoder = CustomJSONDecoder()
XCTAssertThrowsError(try jsonDecoder.decode(to: ExpoIntroduction.self, from: "invalidJSONFile")) { (error) in
XCTAssertEqual(error as? ExpoAppError, ExpoAppError.invalidJSONFile)
} // 유효하지 않은 파일 이름을 입력하면 에러를 던질텐데, 던지는 에러가 `ExpoAppError.invalidJSONFile`가 맞는지 검증!
}
코드 작성 스타일 관련
테스트 코드에서도 암시적 옵셔널 타입(!
) 사용 지양. 일반 옵셔널(?
) 활용 후 throw error
PR을 보내면서 아래와 같은 질문을 했어요.
요점은 테스트를 할 때는 nil
이 할당되면 안되는 곳에서 nil
이 검출되면 안되니 에러 발생 확인이 용이하도록 암시적 추출 옵셔널 타입(!
)을 썼는데 어떤가요? 라는 말입니다. 이에 대한 야곰의 답변은..?
이후 야곰의 코멘트와 연계해서 이유 없이 nil
이 검출되는 것은 왜 에러가 발생했는지 확인하기 어렵기 때문에 이런 방식의 프로그래밍은 지양하시는듯해요. 그래서 제 코드도 System Under Test (SUT)
인스턴스들에 대해 암시적 추출 옵셔널 타입을 일반 옵셔널로 변경했습니다 (!
-> ?
).
Result 타입 활용한 에러 처리 방식 학습
지나가는 말씀으로 "반환 받을 타입이 문제라면 Result
타입이라는 멋진 제네릭 타입이 있다"고 말씀하셨어요. 사실 의도를 정확하게 파악하지는 못했지만 오늘 해당 타입을 공부하고 Push를 보내며 추가 질문을 남겼답니다.
본문에 제가 작성했듯이 에러를 던지는 (throw)
것이 아니라 반환 (return)
하므로 에러 처리를 위해 do-catch
문을 작성하지 않아도 되므로 이 메서드를 호출할 때 번거로운 일이 줄고 메서드의 실행의 결과가 성공인지 실패인지 더 명확해진다는 장점이 있을 것 같아요. 더욱이 메서드 실행 시 실패의 결과가 nil
인 것 보다 훨씬 의미가 잘 전달될겁니다. 하지만 아직 의도를 정확히 이해하지 못해서 실제 코드에 반영하지는 않았습니다. Swift는 알면 알수록 정말 재미있는 언어네요.
Class Diagram
관련
자주 사용하는 프로토콜은 채택 사실만 확인할 수 있도록 Class Diagram에 표시
오호..! 바로 반영~!
만국박람회 프로그램 Class Diagram 1차 수정본 작성
기타
testExample() 메서드 관련 오해 해소
저는 testExample()
메서드를 지금까지 테스트 메서드 목록을 적으면 해당 메서드들을 실행해주는 메서드라고 오해하고 있었어요. 이 번 기회에 주석을 다시 읽어보고 위 캡처 내용처럼 해당 메서드와 주석에 대해 다시 생각해보는 기회를 가졌습니다.
PR 피드백 반영 후 추가 커밋 push 🚀
다음 단계로 가즈아~~! 🔥
이제 정말 UI와의 싸움인가..?
추가로 공부해볼 것
Result 타입을 활용한 에러 처리
Opaque Type (불명확 타입)
Enumeration의 Associated value
Author And Source
이 문제에 관하여([TIL] 21.04.07.(Wed)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ryan-son/TIL-21.04.07.Wed저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)