如何在Obj-C中测试发出HTTP请求并解析响应数据的类? [英] How to test a class that makes HTTP request and parse the response data in Obj-C?
问题描述
我有一个需要向服务器发出HTTP请求才能获取一些信息的类.例如:
I Have a Class that needs to make an HTTP request to a server in order to get some information. For example:
- (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对Hole框架进行单元测试,但是问题是我需要模拟/伪造NSURLConnection响应才能测试不同的场景,并且因为我无法在服务器来测试我的框架.
The things is that I'm unit testing (using OCUnit) the hole framework but the problem is that I need to simulate/fake what the NSURLConnection is responding in order to test different scenarios and because I can't relay on the server to test my framework.
所以问题是哪种方法是最好的?
推荐答案
测试调用诸如NSURLConnection sendSynchronousRequest
有两个选项:
a)使用马特·加拉格尔的invokeSupersequent宏拦截呼叫.您的单元测试将包含以下代码:
a) Use Matt Gallagher's invokeSupersequent macro to intercept the call. Your unit test would contain code like this:
@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
设置为强制其拦截呼叫并返回测试数据.
Then you set someFlagYourTestUsesToInterceptTheCall
to force it to intercept the call and return your test data.
b)另一种选择是在被测类中将该调用移到其自己的方法中:
b) Another alternative is to move that call into its own method in your class under test:
-(NSData *)retrieveNewsCount:(NSURLRequest *)request {
NSHTTPURLResponse *response;
NSError *error;
return [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
}
然后使用OCMock在测试用例中拦截该调用:
Then intercept that call in your test case using 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
只是拦截对对象方法的调用,以便在测试时注入一些测试数据.
In this case, OCMock's stub:andCall:onObject:someMethod
intercepts just this call to your object's method in order to inject some test data at test time.
这篇关于如何在Obj-C中测试发出HTTP请求并解析响应数据的类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!