Tôi có một ứng dụng Swift sử dụng NSFetchedResultsController
để lấy List
đối tượng từ cửa hàng khăng khăng:Làm thế nào để đơn vị kiểm tra NSFetchedResultsController trong Swift
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)")
}
và nó hoạt động như mong đợi, tôi nhận được List
đối tượng giới thiệu in ra đến giao diện điều khiển. Tôi muốn viết một số bài kiểm tra đơn vị cho ứng dụng của mình, vì vậy tôi đã tạo lớp mở rộng XCTestCase
. Mã biên dịch mà không có vấn đề gì, kiểm tra chạy, nhưng tiếc là tôi không thể tìm nạp các đối tượng List
trong ngữ cảnh đó.
Tất cả tôi nhận được trong giao diện điều khiển là đếm List
đối tượng và một lỗi nghiêm trọng:
lists count = 59
fatal error: NSArray element failed to match the Swift Array Element type
vươn bởi dòng:
for list: List in lists {
Tôi khá chắc chắn tôi có mục tiêu cấu hình đúng, vì tôi có thể tạo đối tượng List
và chèn nó vào ngữ cảnh đối tượng được quản lý mà không gặp sự cố nào từ mã nguồn của ứng dụng của tôi cũng như từ mã nguồn thử nghiệm đơn vị. Vấn đề duy nhất tôi gặp phải là tìm nạp từ đơn vị kiểm tra. Tôi tự hỏi tại sao tìm nạp đang hoạt động khi chạy ứng dụng trong trình mô phỏng và không thành công khi được thực thi trong khi kiểm tra đơn vị.
Bất kỳ ý tưởng nào có thể sai sẽ được đánh giá cao.
Cập nhật:
Để cụ thể hơn cách thực hiện của tôi trông như thế nào, đây là mẫu mã hoàn chỉnh mà tôi đang chơi với:
var error: NSError? = nil
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
let applicationDocumentsDirectory = urls[urls.count-1] as NSURL
let 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 = coordinator
let 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.fetchedObjects
if 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")
}
Khi tôi thực hiện nó từ mã nguồn ứng dụng của tôi, chạy ứng dụng trong trình mô phỏng, đầu ra giao diện điều khiển trông giống như sau:
Fetched objects count: 3
Fetched 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: 3
Fetched 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";
})
Tuy nhiên, khi tôi thực thi mã này từ kiểm tra đơn vị, tôi nhận được kết quả này:
Fetched objects count: 3
Fetched 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
Tôi hy vọng nó sẽ dễ hiểu hơn về vấn đề ở đâu. Bằng cách nào đó, tuyên bố này:
let fetchedLists: [List]? = fetchedResultsController.fetchedObjects as? [List]
sản xuất một loạt các đối tượng List
khi ứng dụng được chạy trong mô phỏng, nhưng nó vẫn thất bại sản nil
khi được thực thi từ kiểm tra đơn vị.
Bạn có tệp mô hình đối tượng ('momd') được bao gồm trong gói thử nghiệm của mình không? Và là thiết lập tệp mô hình để sử dụng phân lớp 'Danh sách' của bạn cho thực thể danh sách? – MrAlek
@MrAlek - Tôi không chắc liệu tệp '.momd' của tôi có được bao gồm trong gói thử nghiệm hay không. Tôi đang tạo mô hình như thế: 'NSManagedObjectModel (NSBundle.mainBundle(). URLForResource (" CheckLists ", withExtension:" momd ")!)' Và nó làm việc cho mục tiêu chính cũng như mục tiêu thử nghiệm. Bạn có thể đặc sắc hơn không? – Darrarski
@MrAlek - Trong tệp '.xcdatamodeld' của tôi, tôi đã thiết lập đúng lớp cho thực thể' List'. Tôi thậm chí có thể tạo ra thực thể mới trong các bài kiểm tra đơn vị của tôi và chèn nó vào ngữ cảnh. Nó tồn tại trong cơ sở dữ liệu khi ngữ cảnh được lưu. – Darrarski