表示のために使ったりする 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
この記事が気に入ったらサポートをしてみませんか?