插入时的 SwiftData 单元测试 EXC_BREAKPOINT

问题描述 投票:0回答:1

你好,

我正在尝试对 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。

有人知道为什么吗?

谢谢你!

swift swiftui xctest swiftdata swift-data-modelcontext
1个回答
0
投票

在这两种情况下,

modelContainer
都是一个计算属性,当您访问它时,它总是返回一个new
ModelContainer

在第一种情况下,您只需将

modelContext
ModelContainer
中取出,而不握住
ModelContainer
。结果,
ModelContainer
被释放,现在只剩下一个没有关联容器的
ModelContext

在第二种情况下,您do

ModelContainer
存储为Tests类的
存储属性
,因此测试用例使其保持活动状态。

用于访问模型上下文的确切语法并不真正相关。这里的关键点是您是否保持计算属性返回的

ModelContainer
处于活动状态。如果你觉得
container.mainContext
太长,你可以在
Tests
类中编写这样的计算属性。

var modelContext: ModelContext { container.mainContext }
© www.soinside.com 2019 - 2024. All rights reserved.