我正在尝试清理我写的单元测试。
@implementation CTFUserTests {
CoreDataService *_service;
RKObjectManager *_manager;
CTFAPIMappings *_mapping;
}
- (void)setUp {
_service = [[CoreDataService alloc] initForUnitTesting];
_manager = [[RKObjectManager alloc] init];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:_service.managedObjectModel];
_manager.managedObjectStore = managedObjectStore;
NSBundle *bundle = [NSBundle bundleWithIdentifier:[[NSBundle mainBundle].bundleIdentifier stringByAppendingString:@"Tests"]];
[RKTestFixture setFixtureBundle:bundle];
_mapping = [[CTFAPIMappings alloc] initWithManager:_manager];
[super setUp];
}
- (void)tearDown {
_service = nil;
_manager = nil;
[super tearDown];
}
这是返回RKEntityMapping
的方法:
- (RKEntityMapping *)simpleUserMapping {
RKEntityMapping *userMapping =
[RKEntityMapping mappingForEntityForName:NSStringFromClass([CTFUser class]) inManagedObjectStore:_mapping.manager.managedObjectStore];
[userMapping addAttributeMappingsFromDictionary:[_mapping userMappingDict]];
return userMapping;
}
以下是测试:
- (void)testUserResponseMApping {
id parsedJSON = [RKTestFixture parsedObjectWithContentsOfFixture:@"user-response.json"];
/// Configure mapping
RKEntityMapping *userMapping = [self simpleUserMapping];
RKMappingTest *test = [RKMappingTest testForMapping:userMapping sourceObject:parsedJSON destinationObject:nil];
test.managedObjectContext = _service.managedObjectContext;
RKPropertyMappingTestExpectation *usernameExpectation =
[RKPropertyMappingTestExpectation expectationWithSourceKeyPath:@"username" destinationKeyPath:@"username" value:@"tomkowz12"];
[test addExpectation:usernameExpectation];
[test verify];
这里一切都好。测试通过。 但我想要的是创建一些类,我可以定义并返回调用服务器所需的所有映射。它听起来像是映射的单例。所以就是这样。
@interface CTFAPIMappings : NSObject
@property (readonly) RKObjectManager *manager;
+ (instancetype)sharedInstance;
+ (void)setSharedInstance:(CTFAPIMappings *)sharedInstance;
- (instancetype)initWithManager:(RKObjectManager *)manager;
- (RKEntityMapping *)userMapping;
- (NSDictionary *)userMappingDict;
@end
-userMapping
方法的实现与单元测试类中的上述方法-simpleUserMapping
相同。如上所述,方法-simpleUserMapping
使用的_mapping
对象类型为CTFAPIMappings
。因此CTFAPIMappings
的方法也是如此,但使用self而不是_mapping
。
@implementation CTFAPIMappings
…
- (RKEntityMapping *)userMapping {
RKEntityMapping *userMapping =
[RKEntityMapping mappingForEntityForName:NSStringFromClass([CTFUser class]) inManagedObjectStore:_manager.managedObjectStore];
[userMapping addAttributeMappingsFromDictionary:[self userMappingDict]];
return userMapping;
}
CTFAPIMappings
对象初始化时使用RKObjectManager
方法初始化-setUp
。所以它与测试方法中的RKObjectManager
相同。当我替换时,问题出现在testUserResponseMapping
方法中:
RKEntityMapping *userMapping = [self simpleUserMapping];
使用:
RKEntityMapping *userMapping = [_mapping userMapping];
并在-performMapping
类中的方法RKMappingTest
上测试崩溃:
[NSException raise:NSInternalInconsistencyException format:@"%p: failed with error: %@\n%@ during mapping from %@ to %@ with mapping %@",
崩溃日志如下所示:
<unknown>:0: error: -[CTFUserTests testUserResponseMApping] : 0x8d96f30: failed with error: (null)
RKMappingTest Expectations: (
"map 'username' to 'username' with __NSCFConstantString value 'tomkowz12'"
)
Events: (
) during mapping from <CFBasicHash 0x8d7ef90 [0x2267ec8]>{type = immutable dict, count = 5,
entries =>
1 : <CFString 0x8d70d00 [0x2267ec8]>{contents = "password"} = <CFString 0x8d70d20 [0x2267ec8]>{contents = "password123"}
2 : <CFString 0x8d76bb0 [0x2267ec8]>{contents = "username"} = <CFString 0x8d76600 [0x2267ec8]>{contents = "tomkowz12"}
3 : <CFString 0x8d7d160 [0x2267ec8]>{contents = "location"} = <CFArray 0x8d7ef70 [0x2267ec8]>{type = immutable, count = 2, values = (
0 : <CFNumber 0x8faef40 [0x2267ec8]>{value = +10, type = kCFNumberSInt32Type}
1 : <CFNumber 0x8d7d180 [0x2267ec8]>{value = +20, type = kCFNumberSInt64Type}
)}
4 : <CFString 0x8d94f50 [0x2267ec8]>{contents = "email"} = <CFString 0x8d76620 [0x2267ec8]>{contents = "tmk.szlc@gmail.com"}
6 : <CFString 0x8d92860 [0x2267ec8]>{contents = "nick"} = <CFString 0x8d7d140 [0x2267ec8]>{contents = "black_lord"}
}
to (null) with mapping <RKEntityMapping:0x8d7a8d0 objectClass=CTFUser propertyMappings=(
"<RKAttributeMapping: 0x8d7a300 password => password>",
"<RKAttributeMapping: 0x8d732b0 username => username>",
"<RKAttributeMapping: 0x8d77fe0 location => location>",
"<RKAttributeMapping: 0x8d95db0 email => email>",
"<RKAttributeMapping: 0x8d7ce60 nick => nick>"
)>
(
0 CoreFoundation 0x0211c5e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x01e9f8b6 objc_exception_throw + 44
2 CoreFoundation 0x0211c3bb +[NSException raise:format:] + 139
3 Capture The FlagTests 0x098f08ab -[RKMappingTest performMapping] + 1067
4 Capture The FlagTests 0x098f0f53 -[RKMappingTest verify] + 99
5 Capture The FlagTests 0x09801e35 -[CTFUserTests testUserResponseMApping] + 517
6 CoreFoundation 0x02110d1d __invoking___ + 29
7 CoreFoundation 0x02110c2a -[NSInvocation invoke] + 362
8 XCTest 0x201032bf -[XCTestCase invokeTest] + 212
9 XCTest 0x2010338d -[XCTestCase performTest:] + 111
10 XCTest 0x2010417c -[XCTest run] + 82
11 XCTest 0x20102a44 -[XCTestSuite performTest:] + 139
12 XCTest 0x2010417c -[XCTest run] + 82
13 XCTest 0x20102a44 -[XCTestSuite performTest:] + 139
14 XCTest 0x2010417c -[XCTest run] + 82
15 XCTest 0x20102a44 -[XCTestSuite performTest:] + 139
16 XCTest 0x2010417c -[XCTest run] + 82
17 XCTest 0x20105aa1 +[XCTestProbe runTests:] + 183
18 Foundation 0x01ad612c __NSFireDelayedPerform + 372
19 CoreFoundation 0x020dabd6 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
20 CoreFoundation 0x020da5bd __CFRunLoopDoTimer + 1181
21 CoreFoundation 0x020c2628 __CFRunLoopRun + 1816
22 CoreFoundation 0x020c1ac3 CFRunLoopRunSpecific + 467
23 CoreFoundation 0x020c18db CFRunLoopRunInMode + 123
24 GraphicsServices 0x03ae29e2 GSEventRunModal + 192
25 GraphicsServices 0x03ae2809 GSEventRun + 104
26 UIKit 0x00c0dd3b UIApplicationMain + 1225
27 Capture The Flag 0x0000a27d main + 141
28 libdyld.dylib 0x0275a70d start + 1
29 ??? 0x00000008 0x0 + 8
)
我花了大约4个小时的时间,并没有看到任何我错过的东西。对我来说一切都很好,但测试没有通过。我的清理有什么问题?我错过了什么?
提前谢谢。
修改 的
我在测试中创建的注释为RKOBjectManager
实例的等式CTFAPIMappings
添加以下测试。
- (void)testInstanceShouldHaveTheSameManagerAndStoreAsInjected {
RKObjectManager *objectManager = [[RKObjectManager alloc] init];
RKManagedObjectStore *store = [[RKManagedObjectStore alloc] initWithPersistentStoreCoordinator:_service.persistentStoreCoordinator];
[store createManagedObjectContexts];
objectManager.managedObjectStore = store;
CTFAPIMappings *mappings = [[CTFAPIMappings alloc] initWithManager:objectManager];
XCTAssertNotNil(mappings, @"");
XCTAssertNotNil(mappings.manager, @"");
XCTAssertEqualObjects(mappings.manager, objectManager, @"");
XCTAssertEqualObjects(mappings.manager.managedObjectStore, objectManager.managedObjectStore, @"");
}
这是一个简单的测试,它检查两个映射的相等性(对象是否相等):
RKEntityMapping *localCharacterMapping = [self userMapping];
RKEntityMapping *mappingsCharacterMapping = [_mappings userMapping];
XCTAssertEqualObjects(localCharacterMapping.entity, mappingsCharacterMapping.entity, @"");
XCTAssertEqualObjects(localCharacterMapping.persistentStore, mappingsCharacterMapping.persistentStore, @"");
NSLog(@"local = %@", localCharacterMapping);
NSLog(@"mappi = %@", mappingsCharacterMapping);
并记录:
2013-12-07 15:12:07.094 Capture The Flag[27712:70b] local = <RKEntityMapping:0x8ee9ac0 objectClass=CTFUser propertyMappings=(
"<RKAttributeMapping: 0x8e91c00 password => password>",
"<RKAttributeMapping: 0x8ebeb50 username => username>",
"<RKAttributeMapping: 0x8ecb830 location => location>",
"<RKAttributeMapping: 0x8e94730 email => email>",
"<RKAttributeMapping: 0x8ec5d90 nick => nick>",
"<RKRelationshipMapping: 0x8eebef0 characters => characters>"
)>
2013-12-07 15:12:07.096 Capture The Flag[27712:70b] mappi = <RKEntityMapping:0x8eec060 objectClass=CTFUser propertyMappings=(
"<RKAttributeMapping: 0x8eed020 password => password>",
"<RKAttributeMapping: 0x8e8a910 username => username>",
"<RKAttributeMapping: 0x8eb5a30 location => location>",
"<RKAttributeMapping: 0x8e86620 email => email>",
"<RKAttributeMapping: 0x8e92490 nick => nick>",
"<RKRelationshipMapping: 0x8eee3d0 characters => characters>"
)>
答案 0 :(得分:0)
好的,我查了一下。问题出在Cocoapods。在家里,我0.22,在办公室,我有0.27。更新到0.28之后,更新pod之后一切正常。 - Tomasz Szulc刚刚编辑