这与乔恩的回应类似,但无法将其放入评论中。第一步是确保您没有创建真正的连接。实现此目的的最简单方法是将连接的创建拉入工厂方法,然后在测试中替换该工厂方法。有了 OCMock 的部分模拟支持,这可能看起来像这样。
在你的真实课堂上:
- (NSURLConnection *)newAsynchronousRequest:(NSURLRequest *)request
{
return [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
在你的测试中:
id objectUnderTest = /* create your object */
id partialMock = [OCMockObject partialMockForObject:objectUnderTest];
NSURLConnection *dummyUrlConnection = [[NSURLConnection alloc]
initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"file:foo"]]
delegate:nil startImmediately:NO];
[[[partialMock stub] andReturn:dummyUrlConnection] newAsynchronousRequest:[OCMArg any]];
现在,当您的测试对象尝试创建 URL 连接时,它实际上会获取在测试中创建的虚拟连接。虚拟连接不必是有效的,因为我们没有启动它并且它永远不会被使用。如果您的代码确实使用了该连接,您可以返回另一个模拟,一个模拟 NSURLConnection 的模拟。
第二步是调用对象上触发 NSURLConnection 创建的方法:
[objectUnderTest doRequest];
因为被测试的对象没有使用真正的连接,所以我们现在可以从测试中调用委托方法。对于 NSURLResponse,我们使用另一个模拟,响应数据是从测试中其他地方定义的字符串创建的:
int statusCode = 200;
id responseMock = [OCMockObject mockForClass:[NSHTTPURLResponse class]];
[[[responseMock stub] andReturnValue:OCMOCK_VALUE(statusCode)] statusCode];
[objectUnderTest connection:dummyUrlConnection didReceiveResponse:responseMock];
NSData *responseData = [RESPONSE_TEXT dataUsingEncoding:NSASCIIStringEncoding];
[objectUnderTest connection:dummyUrlConnection didReceiveData:responseData];
[objectUnderTest connectionDidFinishLoading:dummyUrlConnection];
就是这样。您已经有效地伪造了被测对象与连接的所有交互,现在您可以检查它是否处于应有的状态。
如果您想查看一些“真实”代码,请查看 CCMenu 项目中使用 NSURLConnections 的类的测试。这有点令人困惑,因为测试的类也被命名为连接。