我正在开发一个自定义网络库并为它编写一些单元测试用例。 我不知道该怎么做。
我有一个RequestObject,它是NSOperation的子类
@interface RequestOperation : NSOperation @property (nonatomic, strong) NSURLRequest *URLRequest; @property (nonatomic, strong, readonly) NSURLResponse *URLResponse; @property (nonatomic, strong, readonly) NSError *connectionError; @property (nonatomic, strong, readonly) NSData *responseData; -(id)initWithURLRequest:(NSURLRequest*)request; @end
在实施中,我有一个私有类别,其中包含NSURLConnection。
我想写一个测试用例来检查发送请求后是否存在URLResponse
-(void)testIfResponseExist { NSURL *url = [[NSURL alloc] initWithString:@"https://google.com"]; NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; myRequest = [[RequestOperation alloc] initWithURLRequest:request]; [myRequest start]; [self WaitFor:1]; XCTAssertNotNil(myRequest.URLResponse, @"Response should not be nil"); }
这种单元测试方式是否正确?
现在这是将实际请求发送到服务器。但是,我也可以存根NSURLConnection并发送虚拟响应。但我不确定应该走哪条路。 模拟对象的优点和缺点是什么?
答案 0 :(得分:1)
您的测试对于测试库似乎是正确的,但我相信Mocking对象更适合应用程序测试。您不希望对您的库测试模型进行模拟,而是在您的应用中使用您的库进行测试。
我将举例说明具有单元测试的模拟对象的强大功能。
我刚刚帮助在大量下载的iOS应用上编写了自动化框架。我们使用OCMock
和KiF
来实际自动化应用内容更新。在我们的自动化测试中,我们使用与应用程序执行内容更新相同的完全代码。但是,我们OCMock
返回内容网址并让它返回不同内容网址的方法。这与swizzling
非常相似。现在,应用程序将指向我们的测试URL,以便在测试时下载内容更新。使用1-2行代码,我们无需编写任何自定义代码就可以换出URL。
id mock = [OCMockObject mockForClass:[MasterUpdater class]];
[[[mock stub] andReturn:[NSString stringWithFormat:@"URL",BASE_UPDATE_TEST_URL]] getMasterUpdateURL];
有了这个,MasterUpdater:getMasterUpdateURL返回了一个自定义URL。我们在单元测试中必须做的就是为我们切换自动测试的URL!
如果我们没有使用模拟,那么我们会在生产代码中编写额外的代码/方法来处理我们的自动化测试。