【iOS】应用XCTest对异步任务进行单元测试

问题提出:

XCTest是xcode内置的单元测试框架,方便我们对那些不依赖UI的业务模块做单元测试,但是对于一些网络模块的异步调用,需要将测试模块的生命周期延长,等回调成功才释放。

那么我们如体利用XCTest做异步单元测试呢?比如:如何对http网络接口做单元测试?


解决方案

由于XCTest是中只一个主线程,且并没有维护一个NSRunLoop,如果需要异步调用做单元测试,需要自己管理NSRunLoop




更好的解决

GitHub大神已经很优雅的解决了这个问题


//
//  XCTest+Async.h
//
//  Created by Saül Baró on 10/29/13.
//  Copyright (c) 2013 Wide Eyes Solutions SL. All rights reserved.
//

#import <XCTest/XCTest.h>

#define ASYNC_TEST_START    __block BOOL hasCalledBack = NO;
#define ASYNC_TEST_DONE     hasCalledBack = YES;
#define ASYNC_TEST_END      NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:10]; \
                            while (hasCalledBack == NO && [loopUntil timeIntervalSinceNow] > 0) { \
                                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:loopUntil]; \
                            } \
                            if (!hasCalledBack) { XCTFail(@"Timeout"); }

#define ASYNC_TEST_END_LONG_TIMEOUT \
                            NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:120]; \
                            while (hasCalledBack == NO && [loopUntil timeIntervalSinceNow] > 0) { \
                                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:loopUntil]; \
                            } \
                            if (!hasCalledBack) { XCTFail(@"Timeout"); }

@interface XCTest (Async)

@end


如何使用

将  XTest+Async.h 这个分类头文件引入测试例类, 看下面的实例

ASYNC_TEST_START   异步任务开始
ASYNC_TEST_DONE   异步任务完成
ASYNC_TEST_END   异步任务超时,10秒
ASYNC_TEST_END_LONG_TIMEOUT 设置异步任务超时时间,120秒

// 引入头文件 
import "XCTest+Async.h"
- (void)testExample
{
    ASYNC_TEST_START;
    dispatch_queue_t kBgQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(kBgQueue, ^{
        NSData* repositoryData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://api.github.com/repos/mobilejazz/XCTest-Async"]];
        NSError* error;
        if (repositoryData) {
            NSDictionary* repositoryInfo = [NSJSONSerialization JSONObjectWithData:repositoryData
                                                                           options:kNilOptions
                                                                             error:&error];
            if (error) {
                XCTFail(@"The data was not a dictionary");
            }
            else {
                XCTAssertNotNil(repositoryInfo, @"XCTest-Async repo:");
                NSLog(@"Repos %@", repositoryInfo);
            }
        }
        else {
            XCTFail(@"The operation couldn't be completed");
        }
        ASYNC_TEST_DONE;
    });
    ASYNC_TEST_END;
}

 
  



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ruglcc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值