[英]Unit testing Parse framework iOS
我正在嘗試為使用Parse后端框架的iOS應用程序編寫單元測試,經過大量實驗似乎未能成功編寫單元測試。 我發現了一些關於測試異步代碼( 在iOS中測試單元測試中的異步調用 )和測試網絡調用的帖子,但我還沒有找到一種方法來測試使用異步回調調用Parse后端。
舉個例子,有人可以建議我如何測試以下代碼行:
[PFUser saveUser:userModelMock withBlock:^(BOOL success, NSError *error) {
}];
我正在使用OCMock和XCTest框架。
任何幫助將非常感激。
*編輯*這是我到目前為止,但似乎失敗了
- (void)testSaveUser {
id userModelMock = [OCMockObject niceMockForClass:[UserModel class]];
id userControllerMock = [OCMockObject niceMockForClass:[self.userController class]];
[[userModelMock expect] saveInBackgroundWithBlock:[OCMArg any]];
[[userControllerMock stub] saveUser:userModelMock withBlock:[OCMArg any]];
[userModelMock verify];
}
如果您不介意使用第三方庫,則可以使用以下方法:
#import <XCTest/XCTest.h>
#import <RXPromise/RXPromise.h>
...
@interface PFUserTests : XCTestCase
@end
@implementation PFUserTests
// helper:
- (RXPromise*) saveUser:(User*)user {
RXPromise* promise = [[RXPromise alloc] init];
[PFUser saveUser:user withBlock:^(Bool success, NSError*error){
if (success) {
[promise fulfillWithValue:@"OK"];
}
else {
[promise rejectWithReason:error];
}
}];
return promise;
}
// tests:
-(void) testSaveUser
{
User* user = ... ;
RXPromise* promise = [self saveUser:user];
// set a timeout:
[promise setTimeout:5.0];
[promise.thenOn(dispatch_get_main_queue(), ^id(id result) {
XCTAssertTrue([result isEqualToString:@"OK"], @"");
XCTAssertTrue( ... , @"");
return nil;
}, ^id(NSError* error) {
// this may fail either due to a timeout or when saveUser fails:
XCTFail(@"Method failed with error: %@", error);
return nil;
}) runLoopWait]; // suspend the run loop, until after the promise gets resolved
}
幾點說明:
您可以在任何隊列上執行成功或失敗處理程序(使用thenOn
語句為promise進行注冊),只需指定隊列即可。 這並沒有死鎖主線程,即使處理程序在主線程上顯式執行,並且測試也在主線程上運行(由於運行循環機制)。
runLoopWait
方法將進入一個運行循環,並且只有在解析了promise后才返回。 這既有效又有效。
承諾接受超時。 如果超時到期,則承諾將被“拒絕”(已解決)並帶有相應的錯誤。
IMO,promises是處理常見異步編程問題的寶貴工具 - 而不僅僅是單元測試的幫助器。 (另見:維基文章期貨和承諾 。
請注意,我是RXPromise庫的作者,因此我完全有偏見;)
Objective-C還有其他Promise實現。
原來這只是因為我缺乏對單元測試的理解。 在對模擬對象,存根等進行一些研究之后,我提出了:
- (void)testSaveUser {
id userModelMock = [OCMockObject mockForClass:[UserModel class]];
id userControllerMock = [OCMockObject partialMockForObject:self.userController];
[[userModelMock expect] saveInBackgroundWithBlock:[OCMArg any]];
[userControllerMock saveUser:userModelMock withBlock:[OCMArg any]];
[userModelMock verify];
}
使用https://github.com/hfossli/AGAsyncTestHelper/中的宏WAIT_WHILE(<expression>, <time_limit>)
,您可以編寫
- (void)testSaveUser
{
__block BOOL saved = NO;
[PFUser saveUser:userModelMock withBlock:^(BOOL success, NSError *error) {
saved = YES;
}];
WAIT_WHILE(!saved, 10.0, @"Failed to save user within 10 seconds timeframe);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.