はじめに
昨日、Realmを使ってみたという記事を書きました。
それに関連してRealmのテストを書く際にMockを読み込む場面があったので記録しておきます。
必要ツール
事前準備
RealmEntity
public class RealmEntity: Object {
@Persisted(primaryKey: true) public var id: Int = 0
}
RealmRepositoryProtocol
public protocol RealmRepositoryProtocol {
func get() -> Results<RealmEntity>
func add(_ bookmark: RealmEntity) throws
func delete(_ bookmark: RealmEntity) throws
}
public final class RealmRepository: RealmRepositoryProtocol {
let realm: Realm
public init(realm: Realm = try! Realm()) {
self.realm = realm
}
public func get() -> Results<RealmEntity> {
realm.objects(RealmEntity.self)
}
public func add(_ bookmark: RealmEntity) throws {
try realm.write {
realm.add(bookmark)
}
}
public func delete(_ bookmark: RealmEntity) throws {
guard let bookmark = realm.object(ofType: RealmEntity.self, forPrimaryKey: bookmark.id) else {
throw NSError(domain: "primary key not found", code: 0)
}
try realm.write {
realm.delete(bookmark)
}
}
}
やりかた
① Realmオブジェクトを保存する
ContentView
import SwiftUI
struct ContentView: View {
private let repository = RealmRepository()
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
}
.padding()
.onAppear {
let realmEntity = RealmEntity()
realmEntity.id = 100
try? repository.add(realmEntity)
}
}
}
② 保存されてるファイルを取得する
ContentView
import SwiftUI
import RealmSwift
struct ContentView: View {
private let repository = RealmRepository()
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
}
.padding()
.onAppear {
// let realmEntity = RealmEntity()
// realmEntity.id = 100
// try? repository.add(realmEntity)
print(Realm.Configuration.defaultConfiguration.fileURL!)
// ↓ これが出力された ↓
// file:///Users/miyamototaishin/Library/Developer/CoreSimulator/Devices/737336AC-3C03-4CD2-BC16-EAC4B1559152/data/Containers/Data/Application/0A92DBCD-5B9A-4F56-98E8-5E14390F3E18/Documents/default.realm
}
}
}
③ 保存されてるファイルを保存する
ターミナル
open file:///Users/miyamototaishin/Library/Developer/CoreSimulator/Devices/737336AC-3C03-4CD2-BC16-EAC4B1559152/data/Containers/Data/Application/AE835C93-B793-4B0F-9C9D-7179C2BB5A04/Documents/default.realm
④ 保存したファイルをXcodeに取り込む
④ RepositoryMockを作成する
RealmRepositoryMock
public final class RealmRepositoryMock: RealmRepositoryProtocol {
var realm: Realm {
let url = URL(fileURLWithPath: Bundle.main.path(forResource: "default", ofType: "realm")!)
return try! Realm(configuration: Realm.Configuration(fileURL: url, schemaVersion: 4))
}
public func get() -> Results<RealmEntity> {
realm.objects(RealmEntity.self)
}
public func add(_ bookmark: RealmEntity) throws {}
public func delete(_ bookmark: RealmEntity) throws {}
}
⑤ ビルドとプレビューでわける
ContentView
import SwiftUI
import RealmSwift
struct ContentView: View {
@State var items: [RealmEntity] = []
let repository: RealmRepositoryProtocol
var body: some View {
List(items, id: \.id) { item in
Text(item.id.description)
}
.onAppear {
// 起動時にランダムで数値を保存
let realmEntity = RealmEntity()
realmEntity.id = Int.random(in: 0...100)
try? repository.add(realmEntity)
// 保存されたものを取得
items = Array(repository.get())
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(repository: RealmRepositoryMock())
}
}
おわり
シュミレーターの方は起動するたびに数値が増えていきます。
プレビューの方は何回起動しても増えません。
シュミレーター | プレビュー |
---|---|
参考記事