我是OCUnit和OCMock的新手,希望了解有关此测试方法的更多信息。
我知道OCUnit和OCMock创建存根生成模拟对象等的能力......
我有一个特定的用例,我还没有破解。
-(bool) isGameCenterAvailable
{
// Check for presence of GKLocalPlayer API.
Class gcClass = (NSClassFromString(@"GKLocalPlayer"));
// The device must be running running iOS 4.1 or later.
bool isIPAD = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad;
NSString *reqSysVer = (isIPAD) ? @"4.2" : @"4.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);
return (gcClass && osVersionSupported);
}
以下是我对单元测试的问题:
1)NSClassFromString(@“GKLocalPlayer”)是对foundation.h的调用,没有能力存根这个我知道的。
2)[[UIDevice currentDevice] systemVersion]是函数范围内的调用。我的方法调用另一个类(UIDevice)中的方法我想用stub覆盖它们的函数调用,以返回一个固定的答案来练习这个函数的每个路径。
如果在被测试函数范围内实例化类,则不确定是否可以模拟类。
另外一个测试类方法如#1。
重构这里唯一的答案吗?
答案 0 :(得分:1)
对于#1,您可以创建一个检查GKLocalPlayer
API的方法:
-(BOOL)isGKLocalPlayerSupported {
return (NSClassFromString(@"GKLocalPlayer")) != nil;
}
然后你可以模仿那个方法。如果在被测试的类中创建方法,则可以使用部分模拟:
-(void)testIsGameCenterAvailable {
// create gameCenterChecker instance to test...
id mockChecker = [OCMockObject partialMockForObject:gameCenterChecker];
BOOL supported = YES;
[[[mockChecker stub] andReturnValue:OCMOCK_VALUE(supported)] isGKLocalPlayerSupported];
expect([gameCenterChecker isGKLocalPlayerSupported]).toBeTruthy();
}
根据您的项目,将它放在实用程序类中可能更有意义,在这种情况下,您可以模拟实用程序:
-(void)testIsGameCenterAvailable {
id mockUtility = [OCMockObject mockForClass:[MyUtility class]];
[MyUtility setSharedInstance:mockUtility];
BOOL supported = YES;
[[[mockUtility stub] andReturnValue:OCMOCK_VALUE(supported)] isGKLocalPlayerSupported];
// create gameCenterChecker instance to test...
expect([gameCenterChecker isGKLocalPlayerSupported]).toBeTruthy();
}
您可以对系统版本和设备采用相同的方法:
-(NSString *)systemVersion;
-(BOOL)isIpad;