我有以下 SwiftData 模型,并正在尝试为它们编写单元测试。我可以检索数据并筛选非关系属性。不幸的是,这不适用于关系属性,我总是收到错误消息“错误:SQLCoredispatchRequest:异常处理请求:
<NSSQLFetchRequestContext: 0x600003b3ff00> , to-many key not allowed here with userInfo of (null)
我已经尝试解决这个问题好几天了,但不幸的是没有成功。 我想检索输入学生“Bob”的所有课程。有人可以帮助我并解释我做错了什么
@Model
public final class StudentModel {
public var name: String?
@Relationship(inverse: \ClassModel.students)
public var classes: [ClassModel]?
public init(
name: String
) {
self.name = name
}
}
@Model
public final class ClassModel {
public var subject: String?
public var students: [StudentModel]?
public init(
subject: String,
students: [StudentModel] = []
) {
self.subject = subject
self.students = students
}
}
final class ClassesAndStudents: XCTestCase {
private var modelContainer: ModelContainer? = {
let modelConfiguration = ModelConfiguration(isStoredInMemoryOnly: true)
do {
return try ModelContainer(
for: ClassModel.self,
configurations: modelConfiguration
)
}
catch {
XCTFail("Could not create ModelContainer: \(error)")
return nil
}
}()
@MainActor
func testManyToManyFetch() throws {
let sut = self.modelContainer!.mainContext
let studentsA = [
StudentModel(name: "Susan"),
StudentModel(name: "Bob"),
StudentModel(name: "Josie"),
]
let studentsB = [
StudentModel(name: "Susan"),
StudentModel(name: "Josie"),
]
let mathClass = ClassModel(
subject: "Math",
students: studentsA
)
sut.insert(mathClass)
let biologyClass = ClassModel(
subject: "Biology",
students: studentsB
)
sut.insert(biologyClass)
do {
let descriptor = FetchDescriptor<ClassModel>(predicate: #Predicate {
$0.students.flatMap { $0.contains { $0.name == "Bob" } } ?? false
})
let classes = try sut.fetch(descriptor) // ERROR: SQLCore dispatchRequest: exception handling request: <NSSQLFetchRequestContext: 0x600003b46840> , to-many key not allowed here with userInfo of (null)
XCTAssertEqual(classes.count, 1, "There should be 1 class from fetch")
}
catch {
XCTFail("Fetch failed: \(error)")
}
}
}
Joakim Danielson 的回答对我有帮助:
@MainActor
func testManyToManyFetch() throws {
let sut = self.modelContainer!.mainContext
let studentsA = [
StudentModel(name: "Susan"),
StudentModel(name: "Bob"),
StudentModel(name: "Josie"),
]
let studentsB = [
StudentModel(name: "Susan"),
StudentModel(name: "Josie"),
]
let mathClass = ClassModel(
subject: "Math",
students: studentsA
)
sut.insert(mathClass)
let biologyClass = ClassModel(
subject: "Biology",
students: studentsB
)
sut.insert(biologyClass)
do {
let descriptor = FetchDescriptor<StudentModel>(predicate: #Predicate { $0.name == "Bob" })
let classes = try sut.fetch(descriptor).map(\.classes)
XCTAssertEqual(classes.count, 1, "There should be 1 class from fetch")
}
catch {
XCTFail("Fetch failed: \(error)")
}
}