如何在Obj-C中测试发出HTTP请求并解析响应数据的类? [英] How to test a class that makes HTTP request and parse the response data in Obj-C?

查看:85
本文介绍了如何在Obj-C中测试发出HTTP请求并解析响应数据的类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个需要向服务器发出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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆