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

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

학습내용


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

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

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

이 과정에서 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개의 댓글