Realmを使っているプロジェクトでユニットテストを行おうとしたときに若干ハマったので書きます。
コンパイルが通らなかったり、通ってもテストとは関係のないところで足止めを食らったので、その時やったことの備忘録です。
環境(投稿時)
- MacBook Air M1, 2020
- macOS Ventura 13.1
- Xcode:
14.2
- Realm:
10.33.0
- RealmDatabase:
12.13.0
準備
基本的には以下のサイトに従います。
ユニットテスト用のファイルを作ると、以下のようなファイルが作られるはずです。
import XCTest
final class UnitTest: XCTestCase {
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
// 以下略
}
前述の公式の説明に従えば、以下のように記述することで、ユニットテスト用のRealm環境でテストを行うことができます。
つまり、実機やシミュレータでのテストに影響が出ません。
また、テスト後に破棄されるためクリーンアップについても気にする必要がありません。
// ...
override func setUpWithError() throws {
super.setUp()
Realm.Configuration.defaultConfiguration.inMemoryIdentifier = self.name
}
// ...
これで、let realm = try? Realm()
等で作ったユニットテスト用のrealm環境と、実機やシミュレータ上のrealmの環境が分離されます。
あとはテスト用の関数を追加していき、テストを行えばおk、のはず…。
トラブルシューティング
import RealmSwift
ができない
テスト用のターゲットにRealmのライブラリをリンクしていないことが原因です。
TARGETS > (ユニットテスト用のターゲット) > Build Phases > Link Binary LibrariesでRealmを追加します。
注意としてはRealmSwiftは 追加してはいけません 。(次で書きます)
テスト実行時にRealmにオブジェクトを追加できない
以下のようなエラーメッセージが出た場合、
Object type (クラス名) is not managed by the Realm. If using a customobjectClasses
/objectTypes
array in your configuration, add (クラス名) to the list ofobjectClasses
/objectTypes
. (RLMException)
これは、一つ前でも少し書きましたが、RealmSwiftをリンクしていることが原因です。
前述の公式のチュートリアルにも書いてはあります。
Don't link the Realm Database framework directly to your test target. This can cause your tests to fail with an exception message "Object type 'YourObject' is not managed by the Realm." Unlinking Realm Database from your test target should resolve this issue.
ここで言われている "Realm Database framework" をてっきりRealmのことだと思い、RealmSwiftをリンクしてRealmをリンクしないようにしてたのですが、そのせいで何時間かハマりました。
RealmSwiftはリンクせず、Realmだけをリンクしましょう。
ぶっちゃけこの記事ではこれを書きたかっただけです。
2024/04/20追記
この項目について、状況が変わっていたので追記します。
- Realm:
10.49.2
- RealmDatabase:
14.5.2
上記環境では、 RealmSwift
もリンクする必要がありました。
リンクしない場合、以下の画像のように、 Realm
を呼んだときに SIGABORT
します。
他にもつまずいたら追記していきます。