尝试在我的(Swift)单元测试中将获取的NSManagedObject向下转换为正确的子类StoryPhotoTrack
时,我收到运行时错误:Could not cast value of type 'StoryPhotoTrack_StoryPhotoTrack_' (0x7fbda4734490) to 'StoryPhotoTrack' (0x11edd1b08).
这是我的失败/崩溃测试:
func testFetchingStoryWithCastingInvolved() {
let story : StoryPhotoTrack? = storyFetcher.fetchAnyStoryPhotoTrack()
XCTAssertNotNil(story, "should be a story") // works
let definitlyAStory : StoryPhotoTrack = story! // works
let object : NSManagedObject = story as NSManagedObject! // works
println(NSStringFromClass(definitlyAStory.dynamicType)) // prints 'StoryPhotoTrack_StoryPhotoTrack_'
let downCastedStory : StoryPhotoTrack = object as! StoryPhotoTrack // -> error: "Could not cast..."
XCTAssertNotNil(downCastedStory, "should still be a story")
}
// StoryFetcher.swift
func fetchAnyStoryPhotoTrackVia_ObjectiveC_Fetcher() -> StoryPhotoTrack? {
let object = StoryPhotoTrack.fetchAnyStoryPhotoTrackInContext(moc)
return object as StoryPhotoTrack?
}
实际提取在Objective-C中完成:
// StoryPhotoTrack+Fetching.m
+ (StoryPhotoTrack *)fetchAnyStoryPhotoTrackInContext:(NSManagedObjectContext *)moc
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"StoryPhotoTrack"];
NSArray *storyTracks = [moc executeFetchRequest:request error:nil];
return (StoryPhotoTrack *)[storyTracks lastObject];
}
我认为,它与Swift的命名空间有关。好像我的StoryPhotoTrack类实际上被称为StoryPhotoTrack_StoryPhotoTrack_
。
我尝试使用projectName-prefixes重命名我的核心数据实体的类名(如建议的here),但这没有帮助。我尝试了我的主目标模块名称和我的测试目标模块名称,但没有一个工作。
我做错了什么?
编辑:似乎我忽略了像How to test Core Data properly in Swift这样的问题,所以看来,这个问题是众所周知的,但不容易解决。它真的是create a separate framework for your Core Data Model的最佳方式吗?
答案 0 :(得分:0)
我有同样的问题,由于某种原因,我无法转换为我的自定义NSManagedObjects进行单元测试,唯一的解决方案是将结果集保存为NSManagedObject Array并访问它是如下字段而不将其转换为ProductModel,对象本身仍然是一个ProductModel,但是它会导致错误。
我将我的模型名称保留为ProductModel而没有MyAppName.ProductModel。
func testProductModel() {
let resultFetchRequest = NSFetchRequest(entityName: ProductModel.Name)
let productModels: [NSManagedObject] = context.executeFetchRequest(resultFetchRequest, error: &error) as!
[NSManagedObject]
if let recipes = productModels[0].valueForKey("recipes") as? NSSet {
let recipesCount = recipes.count;
XCTAssertTrue(recipesCount == 0)
} else {
XCTFail("FAIL - no recipes nsset")
}
}