見出し画像

表示のために使ったりする enum は Equatable に準拠させておいた方がテストの時に役に立つ

概要

自分はよく TableView に複数の種類のセルを表示させたい時に、値つきの enum を使って実装したりします。

enum CellType {
    // セルに表示させる API から受け取ったレスポンスなど
    case article(with: APIResponse)
    // 画像の URL など
    case image(with: String)
    // ページネーションのためにインジケーターなど
    case indicator
}

MVVM などの場合これを ViewModel から Driver<[CellType]> のように公開してバインディングさせますが、この状態で ViewModel のテストを作ろうとしたところ XCTAssertEqual でイベントを比較しようとした時にエラーになってしまいました。

エラーになった理由は明白で、Equatable に準拠していないためです。
値付きの enum を Equatable に準拠させたのは初めてだったので、忘れないようにまとめておきます。

値付きの enum を Equatable に準拠させる

単に String や Int を値としてもつ enum の場合は、Swift4.1 以降なら Equatable に準拠させるだけで暗黙的に == メソッドを実装してくれます。

enum CellType: Equatable {
   case text(String)
   case image
   
   // == を実装しなくてもいい
}

// テストで比較もできる
XCTAssertNotEqual(CellType.text("TEST"), CellType.image)
XCTAssertEqual(CellType.text("TEST"), CellType.text("TEST"))

しかし自前で作成した構造体等を値としてもつ場合は、構造体も Equatable に準拠させる、もしくは == メソッドを自前で実装する必要があります。

struct APIResponse: Equatable {
   let id: Int
   let content: String?
}

enum CellType: Equatable {
   // 値としてもつ構造体も Equatable に準拠させる
   case article(with: APIResponse)
   case image(with: String)
   case indicator
   
   // もしくは == を自前で実装
}

let dummyAPIResponse = APIResponse(id: 1, content: "TEST")
let dummyImageURL = "TEST"

XCTAssertNotEqual(CellType.article(with: dummyAPIResponse), CellType.image(with: dummyImageURL))
XCTAssertEqual(CellType.article(with: dummyAPIResponse), CellType.article(with: dummyAPIResponse))

== を自前で実装すると case が増えるごとに大変になってくるので、値として持っている構造体等を Equatable 準拠にした方が正直楽かなと思いました。

最後に

テストを書いていると今回のようにコードの細かい部分を改めて見直すことができる気がするので、今までサボっていた分きちんとテストを書いていこうと思います😎

参考

How to make a Swift enum with associated values equatable
Swift 4.1+ - LINE ENGINEERING

この記事が気に入ったらサポートをしてみませんか?