单元测试Parse框架iOS [英] Unit testing Parse framework iOS

查看:109
本文介绍了单元测试Parse框架iOS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为使用Parse后端框架的iOS应用程序编写单元测试,经过大量实验似乎未能成功编写单元测试。我发现了一些关于测试异步代码的帖子(在单元中测试异步调用在iOS中测试)并测试网络调用,但还没有找到一种方法来测试使用异步回调调用Parse后端。

I am attempting to write unit tests for an iOS application which makes use of the Parse backend framework, and after much experimentation seem to be failing at writing successful unit tests. I have found a few posts on testing asynchronous code (Testing asynchronous call in unit test in iOS) and testing network calls, but am yet to find a way of testing calls to the Parse backend with async callbacks.

举个例子,任何人都可以建议我如何测试以下代码行:

To give an example, could anyone advise how I would test the following line of code:

[PFUser saveUser:userModelMock withBlock:^(BOOL success, NSError *error) {

}];

我正在使用OCMock和XCTest框架。

I am using OCMock and the XCTest framework.

任何帮助都会非常感激。

Any help would be much appreciated.

*编辑*
这是我到目前为止所看到的但似乎是失败

* EDIT * This is what I have so far but seems to be failing

- (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];
}


推荐答案

如果你不介意的话要使用第三方库,您可以使用以下方法:

If you don't mind to utilize a third party library, you may use the following approach:

#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 任何队列上的> statement),只需指定队列即可。这并没有死锁主线程,即使处理程序在主线程上显式执行,并且测试也在主线程上运行(由于运行循环机制)。

You can execute the success or failure handler (which are registered for the promise with the thenOn statement) on any queue, just specify the queue. This does not dead lock the main thread, even though the handler gets explicitly executed on the main thread, and the test runs as well on the main thread (thanks to the run loop mechanism).

方法 runLoopWait 将进入运行循环,并且只有在解析了promise后才返回。这既有效又有效。

The method runLoopWait will enter a run loop, and only return once the promise has been resolved. This is both, effective and efficient.

承诺接受超时。如果超时到期,则承诺将被拒绝(已解决)并带有相应的错误。

A promise accepts a timeout. If the timeout expires, the promise will be "rejected" (that is resolved) with a corresponding error.

IMO,promises是处理常见异步编程问题的宝贵工具 - 不仅仅是单元测试的帮手。 (另请参阅:维基文章期货和承诺

IMO, promises are an invaluable tool for handling common asynchronous programming problems - not just a helper for unit tests. (See also: wiki article Futures and promises.

请注意,我是 RXPromise库的作者,因此我完全是有偏见的;)

Please note, I'm the author of the RXPromise library, and thus I'm totally biased ;)

Objective-C还有其他Promise实现。

There are other Promise implementations for Objective-C as well.

这篇关于单元测试Parse框架iOS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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