簡體   English   中英

單元測試Parse框架iOS

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM