你好,
我正在尝试对SwiftData 模型进行单元测试,但遇到了一个奇怪的情况并且找不到问题的答案。
我向您展示的第一个解决方案不起作用,第二个解决方案起作用。
首先,这是我的@Model:
@Model
class Movie {
var name: String
init(name: String) {
self.name = name
}
}
第一个解决方案(不起作用):
var modelContainer: ModelContainer {
do {
let container = try ModelContainer(for: Movie.self, configurations: ModelConfiguration(isStoredInMemoryOnly: true))
return container
} catch {
fatalError("Failed to create container.")
}
}
@MainActor
final class Tests: XCTestCase {
private var context: ModelContext!
override func setUp() {
context = modelContainer.mainContext
}
func testCountShouldBeOne() {
let movie = Movie(name: "NewMovie")
context.insert(movie) // Thread 1: EXC_BREAKPOINT
do {
let descriptor = FetchDescriptor<Movie>()
let movies = try context.fetch(descriptor)
XCTAssertEqual(movies.count, 1)
} catch {
XCTFail()
}
}
}
第二种解决方案(有效):
(modelContainer remains the same)
@MainActor
final class Tests: XCTestCase {
private var container: ModelContainer!
override func setUp() {
container = modelContainer
}
func testCountShouldBeOne() {
let movie = Movie(name: "NewMovie")
container.mainContext.insert(movie)
do {
let descriptor = FetchDescriptor<Movie>()
let movies = try container.mainContext.fetch(descriptor)
XCTAssertEqual(movies.count, 1)
} catch {
XCTFail()
}
}
}
因此,区别在于我现在必须调用 container.mainContext 进行 SwiftData 操作,并且它可以工作,但是在第一个解决方案中,我有:context.something,我得到了 EXC_BREAKPOINT。
有人知道为什么吗?
谢谢 !
在这两种情况下,
modelContainer
都是计算属性,当您访问它时它总是返回一个新的。ModelContainer
在第一种情况下,您只是
modelContext
从 中取出ModelContainer
,而不保留ModelContainer
。ModelContainer
结果 被释放,现在您只剩下ModelContext
,没有关联容器。在第二种情况下,您确实将其存储
ModelContainer
为类的存储属性Tests
,因此测试用例使其保持活动状态。您用于访问模型上下文的确切语法实际上并不重要。这里的关键点是您是否保持
ModelContainer
计算属性返回的值有效。如果您觉得container.mainContext
太长,您可以在Tests
类中编写这样的计算属性。