单元测试中的新核心数据堆栈(PersistenceController)
Posted
技术标签:
【中文标题】单元测试中的新核心数据堆栈(PersistenceController)【英文标题】:New Core Data Stack (PersistenceController) in Unit Tests 【发布时间】:2020-09-16 01:42:57 【问题描述】:使用新的 Swift App Xcode 模板,我看到 PersistenceController
结构添加了 shared
和 preview
实例以用作核心数据堆栈。据我了解,preview
实例用于 SwiftUI 预览。
如果我有一个接受我的核心数据堆栈实例的服务类,我应该使用preview
实例作为我的单元测试的一部分吗?或者我应该创建某种间谍/伪造来传递到我正在测试的服务类中?
一般来说,测试使用 Core Data 的类的最佳实践是什么?
【问题讨论】:
【参考方案1】:我也在研究这个。我没有找到最佳实践。所以我会总结一下我的工作。 PersistenceController 是一个不错的模式。
静态变量预览允许您创建不同的商店并向其中添加一些对象,例如
static var preview: PersistenceController =
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
// this is the part where you can add mock data
for _ in 0..<10
let newItem = Note(context: viewContext)
newItem.creationDate = Date()
do
try viewContext.save()
catch
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
return result
()
对于单元测试,我们希望从一个空存储开始,所以我只是在 PersistenceController 中添加了一个 var
static let unitTest: PersistenceController =
let result = PersistenceController(inMemory: true)
//empty store
return result
()
这使我的单元测试看起来像
class TestCoreDataStack: XCTestCase
var coreDataStack: PersistenceController!
override func setUp()
super.setUp()
coreDataStack = PersistenceController.unitTest
override func tearDown()
super.tearDown()
//called after the invocation of each test method in the class.
// I am deleted all notes to start fresh for the next test
UnitTestHelpers.deleteAllNotes(container: coreDataStack.container)
coreDataStack = nil
func testAddNote()
let context = coreDataStack.container.viewContext
let title = "my new title"
let note = Note(title: title, context: context)
XCTAssertNotNil(note, "note should not be nil")
XCTAssertTrue(note.title == title)
XCTAssertNotNil(note.creationDate, "notes date should not be nil")
【讨论】:
我喜欢这个解决方案,但发现单元测试持久性控制器在测试之间没有重新初始化存在问题,而且我不想每次都手动删除所有内容。最后,我只是在设置中调用coreDataStack = PersistenceController(inMemory: true)
,到目前为止它正在工作。以上是关于单元测试中的新核心数据堆栈(PersistenceController)的主要内容,如果未能解决你的问题,请参考以下文章