我有一个类需要向服务器发出HTTP请求才能获取一些信息。例如:
- (NSUInteger)newsCount {
NSHTTPURLResponse *response;
NSError *error;
NSURLRequest *request = ISKBuildRequestWithURL(ISKDesktopURL, ISKGet, cookie, nil, nil);
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (!data) {
NSLog(@"The user's(%@) news count could not be obtained:%@", username, [error description]);
return 0;
}
NSString *regExp = @"Usted tiene ([0-9]*) noticias? no leídas?";
NSString *stringData = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSArray *match = [stringData captureComponentsMatchedByRegex:regExp];
[stringData release];
if ([match count] < 2)
return 0;
return [[match objectAtIndex:1] intValue];
}
事情是,我是单元测试(使用OCUnit)孔框架,但问题是我需要模拟/伪造NSURLConnection响应的内容,以便测试不同的场景,因为我无法继续服务器来测试我的框架。
所以问题是哪种方法最好?
答案 0 :(得分:4)
测试调用类NSURLConnection sendSynchronousRequest
以下是几个选项:
a)使用Matt Gallagher's invokeSupersequent macro拦截来电。您的单元测试将包含以下代码:
@implementation NSURLConneciton (UnitTests)
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error {
if (someFlagYourTestUsesToInterceptTheCall) {
// return test NSData instance
}
return invokeSupersequent(request, &response, &error);
}
@end
然后设置someFlagYourTestUsesToInterceptTheCall
以强制它拦截调用并返回测试数据。
b)另一种方法是将该调用移动到您测试的类中自己的方法:
-(NSData *)retrieveNewsCount:(NSURLRequest *)request {
NSHTTPURLResponse *response;
NSError *error;
return [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
}
然后使用OCMock在您的测试用例中拦截该调用:
-(void)testNewsCount {
// instantiate your class
id myObject = ...;
id mock = [OCMockObject partialMockForObject:myObject];
[[[mock stub] andCall:@selector(mockNewsCount:) onObject:self] retrieveNewsCount:[OCMArg any]];
NSUInteger count = [myObject newsCount];
// validate response
...
}
// in the same test class:
-(NSData *)mockNewsCount:(NSURLRequest *)request {
// return your mock data
return mockData;
}
在这种情况下,OCMock的stub:andCall:onObject:someMethod
仅拦截对对象方法的调用,以便在测试时注入一些测试数据。