May 18, 2021, TIL (Today I Learned) - enum타입, 이제 이런 실수하지 말자

Inwoo Hwang·2021년 8월 26일
0
post-thumbnail

학습내용


테스트를 위해 아래와 같이 Sample api를 만들어봤습니다.

Screen Shot 2021-05-18 at 10.23.26 PM

그런데 이걸 테스트에서 어떻게 사용하면 좋을까 고민하다가 이렇게 타입으로 먼저 구현했습니다.

Screen Shot 2021-05-18 at 10.22.22 PM

그런데 이렇게 접근하려 하니 optional 바인딩을 통해서 추출하려 하니 nil 값이 반환되는 문제점을 확인하였습니다.

Screen Shot 2021-05-18 at 10.28.24 PM

이 과정에서 enum에 대한 제 지식이 얼마나 많이 부족했는지 깨달았습니다.

그래서 열거형에 대해서 조금 더 공부해 보는 시간을 가졌습니다.

열거형의 활용

열거형은 인스턴스를 만들지 못하나 고민고민 하다가 결국 잘 설명 해 주신 블로거 덕분에 조금이나마 열거형에 대해서 더 알아갈 수 있었습니다. 다시 한 번 감사를...

"열거형은 클래스나 구조체처럼 내부에 연산 프로퍼티와 메소드 또한 정의가 가능하다. 인스턴스를 만들 수는 없지만, 인스턴스처럼 사용할 수 있어서 인스턴스 프로퍼티, 타입 프로퍼티 메소드를 모두 정의할 수 있다."

enum ImageFormat {
	case JPEG
	case PNG(Bool)
	case GIF(Int, Bool)
}

var image = ImageFormat.PNG(true)
	imgae = .GIF(256, false)

이와 같이 열거형을 구성한 뒤 image라는 인스턴스를 case를 통해 선언할 수 있다는 것이 기억이 났습니다.

그래서 이번 프로젝트 테스트에서도 비슷하게 적용 해 보았습니다.

class OpenMarketNetworkTests: XCTestCase {
  // sampleOpenMarketAPI 프로퍼티 구현
  var sampleOpenMarketAPI: SampleOpenMarketAPI!
  
  override func setUpWithError() throws {
    // 열거형을 인스턴스처럼 사용
    sampleOpenMarketAPI = .connection
    try super.setUpWithError()
  }
  
  override func tearDownWithError() throws {
    // 테스트가 끝난뒤 인스턴스 제거
    sampleOpenMarketAPI = nil
  }
}

덕분에 아래 궁금증1을 해소할 수 있었습니다 😁

[참조]:

Swift 열거형(enum)과 익스텐션(extension) | hwiVeloper

궁금증 1

문제

왜 enum type은 인스턴스를 만들고 해당 인스턴스를 통해서 변수에 접근이 불가한가?

sampleOpenMarketAPI.itemListURL

문제이유

해당 변수의 초깃값을 setUpWithError()에 선언하지 않았기 때문

해결방법

  1. 타입을 프로퍼티로 선언한 뒤 setUpWithError()에서 해당 프로퍼티에게 해당되는 열거형의 case를 초깃값으로 할당하여 해결

    override func setUpWithError() throws {
        // 열거형을 인스턴스처럼 사용
        sampleOpenMarketAPI = .connection
        try super.setUpWithError()
      }
  2. 타입 자체로 접근하는 방법

    이 열거형의 타입 → case → 변수 이와 같은 방법으로는 접근이 가능하다.

    SampleOpenMarketAPI.connection.itemListURL 은 된다.

이런식으로 인스턴스를 생성 해 줘도 된다.

궁금증 2

문제점: 이 차이점에 대해 잘 모르겠습니다.....

class OpenMarketAPIProvider {
    let urlSession: URLSession
    
    init(urlSession: URLSession) {
        self.urlSession = URLSession.shared
    }
}
class OpenMarketAPIProvider {
    let urlSession: URLSession
    
    init(urlSession: URLSession = .shared) {
        self.urlSession = urlSession
    }

차이점 Understood

첫 번째 예시는 urlSession 상수에 대해서 초기화를 URLSession 타입의 상수로 초기화를 하는 것이 아니라 URLSession의 shared 세션으로 무조건 초기화를 할 것이라는 것을 뜻한다. 즉 urlSession의 configuration을 바꾸려 입력값을 받더라도 무조건 적으로 URLSession.shared로 초기화가 되는 것이다.

두 번째 예시는 반면에 초기값을 설정할 때 만약 내가 특정한 입력값을 넣지 않는 이상 urlSession의 .shared로 초기화를 할 것이라는 것을 뜻합니다.

profile
james, the enthusiastic developer

0개의 댓글