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

来源:互联网 发布:dna数据库能找人吗 编辑:程序博客网 时间:2024/05/29 16:51

问题提出:

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

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


解决方案

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




更好的解决

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

https://github.com/mobilejazz-contrib/XCTest-Async

////  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;}





1 0
原创粉丝点击