
let fetchedResultsController: NSFetchedResultsController = ...var error : NSError?fetchedResultsController.performFetch(&error)if let error = error { NSLog("Error: \(error)")}let Lists: [List] = fetchedResultsController.fetchedobjects! as [List]NSLog("Lists count = \(Lists.count)")for List: List in Lists { NSLog("List: \(List.description)")} 它的工作方式与预期的一样,我将List对象描述打印到控制台.
我想为我的应用程序编写一些单元测试,所以我创建了扩展XCTestCase的类.代码编译没有问题,测试运行,但不幸的是我无法在该上下文中获取List对象.
我在控制台中获得的所有内容都是List对象的数量和致命错误:
Lists count = 59Fatal error: NSArray element Failed to match the Swift Array Element type
线路上升:
for List: List in Lists { 我很确定我已经正确配置了目标,因为我可以创建List对象并将其插入到托管对象上下文中,而不会出现我的应用程序源代码以及单元测试源代码的问题.我遇到的唯一问题是从测试单元获取.我想知道为什么在模拟器中运行应用程序时提取工作正常,并且在单元测试期间执行时失败.
任何可能出错的想法都将受到赞赏.
更新:
更具体地说,我的实现如何,这里是我正在玩的完整代码示例:
var error: NSError? = nillet urls = NSfileManager.defaultManager().URLsForDirectory(.documentDirectory,inDomains: .UserDomainMask)let applicationdocumentsDirectory = urls[urls.count-1] as NSURLlet modelURL = NSBundle.mainBundle().URLForResource("CheckLists",withExtension: "momd")!let managedobjectModel = NSManagedobjectModel(contentsOfURL: modelURL)var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedobjectModel: managedobjectModel)let url = applicationdocumentsDirectory.URLByAppendingPathComponent("CheckLists.sqlite")if coordinator!.addPersistentStoreWithType(NSsqliteStoreType,configuration: nil,URL: url,options: nil,error: &error) == nil { NSLog("Error1: \(error)") abort()}var managedobjectContext = NSManagedobjectContext()managedobjectContext.persistentStoreCoordinator = coordinatorlet fetchRequest = NSFetchRequest()fetchRequest.entity = NSEntityDescription.entityForname("List",inManagedobjectContext: managedobjectContext)fetchRequest.sortDescriptors = [ NSSortDescriptor(key: "name",ascending: true) ]let fetchedResultsController = NSFetchedResultsController( fetchRequest: fetchRequest,managedobjectContext: managedobjectContext,sectionnameKeyPath: nil,cachename: "ListFetchedResultsControllerCache")fetchedResultsController.performFetch(&error)if let error = error { NSLog("Error2: \(error)") abort()}let fetchedobjects: [AnyObject]? = fetchedResultsController.fetchedobjectsif let fetchedobjects = fetchedobjects { NSLog("Fetched objects count: \(fetchedobjects.count)") for fetchedobject in fetchedobjects { NSLog("Fetched object: \(fetchedobject.description)") }}else { NSLog("Fetched objects array is nil")}let fetchedLists: [List]? = fetchedResultsController.fetchedobjects as? [List]if let fetchedLists = fetchedLists { NSLog("Fetched Lists count: \(fetchedLists.count)") for fetchedList in fetchedLists { NSLog("Fetched List: \(fetchedList.description)") }}else { NSLog("Fetched Lists array is nil")} 当我从应用程序的源代码执行它,在模拟器中运行应用程序时,控制台输出如下所示:
Fetched objects count: 3Fetched object: <CheckLists.List: 0x7a6866f0> (entity: List; ID: 0x7a686020 <x-coredata://7A87B5BE-C2FA-4150-B9E3-879FDE07F0B9/List/p2> ; data: { name = "List 1";})Fetched object: <CheckLists.List: 0x7a686930> (entity: List; ID: 0x7a686030 <x-coredata://7A87B5BE-C2FA-4150-B9E3-879FDE07F0B9/List/p1> ; data: { name = "List 2";})Fetched object: <CheckLists.List: 0x7a686970> (entity: List; ID: 0x7a686040 <x-coredata://7A87B5BE-C2FA-4150-B9E3-879FDE07F0B9/List/p3> ; data: { name = "List 3";})Fetched Lists count: 3Fetched List: <CheckLists.List: 0x7a6866f0> (entity: List; ID: 0x7a686020 <x-coredata://7A87B5BE-C2FA-4150-B9E3-879FDE07F0B9/List/p2> ; data: { name = "List 1";})Fetched List: <CheckLists.List: 0x7a686930> (entity: List; ID: 0x7a686030 <x-coredata://7A87B5BE-C2FA-4150-B9E3-879FDE07F0B9/List/p1> ; data: { name = "List 2";})Fetched List: <CheckLists.List: 0x7a686970> (entity: List; ID: 0x7a686040 <x-coredata://7A87B5BE-C2FA-4150-B9E3-879FDE07F0B9/List/p3> ; data: { name = "List 3";}) 但是,当我从单元测试中执行此代码时,我得到此输出:
Fetched objects count: 3Fetched object: <CheckLists.List: 0x7a07df50> (entity: List; ID: 0x7a07d7e0 <x-coredata://7A87B5BE-C2FA-4150-B9E3-879FDE07F0B9/List/p2> ; data: { name = "List 1";})Fetched object: <CheckLists.List: 0x7a07e190> (entity: List; ID: 0x7a07d7f0 <x-coredata://7A87B5BE-C2FA-4150-B9E3-879FDE07F0B9/List/p1> ; data: { name = "List 2";})Fetched object: <CheckLists.List: 0x7a07e1d0> (entity: List; ID: 0x7a07d800 <x-coredata://7A87B5BE-C2FA-4150-B9E3-879FDE07F0B9/List/p3> ; data: { name = "List 3";})Fetched Lists array is nil 我希望它更容易理解问题所在.不知何故,这句话:
let fetchedLists: [List]? = fetchedResultsController.fetchedobjects as? [List]
当app在模拟器中运行时,会生成一个List对象数组,但是当从单元测试执行时,它无法生成nil.
该问题与目标配置相关联.我通过一些解决方法解决了这个问题.以前,为了使List实体类可以在我的单元测试目标中访问,我已将它添加到此目标.因此,List类有两个目标.实际上,Swift已知有两个List类,每个目标对应一个:MyAppTarget.List和MyUnitTestTarget.List. Retched结果控制器返回MyAppTarget.List对象的数组,但在单元测试目标中,List被假定为MyUnitTestTarget.List类.这就是这行代码:
let fetchedLists: [List]? = fetchedResultsController.fetchedobjects as? [List]
从单元测试目标执行时生成nil,而不是从主目标执行时生成的正确数组.为了解决这个问题,我将其更改为:
let fetchedLists: [MyAppTarget.List]? = fetchedResultsController.fetchedobjects as? [MyAppTarget.List]
并使List类公开.在那次改变之后,它会像预期的那样工作
但是,对我来说,MyAppTarget.List无法转换为MyUnitTestTarget.List有点让人困惑.而且,这意味着我需要公开每个实体NSManagedobject子类,以便在单元测试中使用它.到目前为止,我找不到更好的解决方案.
也许有更好的方法来解决这个问题.我没有看到告诉NSFetchedResultsController它应该返回主目标中的MyAppTarget.List和单元测试目标中的MyUnitTestTarget.List的选项.它将始终使用.xcdatamodeld文件中给定实体的配置.此外,即使有一种方法将MyAppTarget.List转换为单元测试中的MyUnitTestTarget.List,它仍然需要List类是公共的.
更新:
我找到了一种在运行时更改NSFetchedResultsController返回的实体类的方法.这是一个更清晰简单的解决方案:https://stackoverflow.com/a/25858758/514181
它允许在单元测试中无缝地使用CoreData实体,而无需强制转换或使实体类公开.
总结以上是内存溢出为你收集整理的unit-testing – 如何在Swift中对NSFetchedResultsController进行单元测试全部内容,希望文章能够帮你解决unit-testing – 如何在Swift中对NSFetchedResultsController进行单元测试所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)