问题描述
我已经安装了的成X $ C $Ç并按照说明设置单元测试发现。
这一切的伟大工程,我可以测试我的所有对象的精绝我的同步方法。然而,大多数复杂的API其实我是想通过调用一个委托的方法异步测试返回结果 - 例如一个文件的下载和更新系统的调用将立即返回,然后运行-fileDownloadDidComplete:方法时,该文件完成下载
我将如何测试这个作为一个单元测试?
好像我会想的testDownload功能,或至少测试框架,以等待为fileDownloadDidComplete:方法来运行
编辑:我现在已经切换到使用X code内置XCTest系统,并发现在Github上提供了使用信号灯等待异步操作完成死简便的方法。
例如:
- (无效){TESTLOGIN
TRVSMonitor *显示器= [TRVSMonitor显示器]
__block的NSString * theToken; [Server实例] loginWithUsername:@foo的密码:@栏
成功:^(* NSString的令牌){
theToken =记号。
[显示器信号]
} 失败:^(NSError *错误){
[显示器信号]
}]; [显示器等]; XCTAssert(theToken,@获得令牌);
}
我遇到了同样的问题,发现了不同的解决方案,对我的作品。
我用的是老派的方法通过使用信号量,如下转向异步操作成同步流:
//创建一个将执行异步操作的对象
MyConnection的*康恩= MyConnection的新]
STAssertNotNil(康涅狄格州,@MyConnection的初始化失败);//创建信号量并锁定我们开始之前一次
//异步操作
NSConditionLock * TL = [NSConditionLock新]
self.theLock = TL;
[TL发布]//开始异步操作
self.testState = 0;
[康恩doItAsyncWithDelegate:个体经营];//现在锁定信号 - 这将阻止该线程直到
// [self.theLock unlockWithCondition:1]被调用
[self.theLock lockWhenCondition:1];//确保异步回调并实际上是由发生
//检查它是否修改的变量
STAssertTrue(!self.testState = 0,@代表没有得到所谓的);//我们就大功告成了
[self.theLock发布] self.theLock =零;
[康恩发布]
确认调用
[self.theLock unlockWithCondition:1];
在委托(S)即可。
I have installed Google Toolbox for Mac into Xcode and followed the instructions to set up unit testing found here.
It all works great, and I can test my synchronous methods on all my objects absolutely fine. However, most of the complex APIs I actually want to test return results asynchronously via calling a method on a delegate - for example a call to a file download and update system will return immediately and then run a -fileDownloadDidComplete: method when the file finishes downloading.
How would I test this as a unit test?
It seems like I'd want to the testDownload function, or at least the test framework to 'wait' for fileDownloadDidComplete: method to run.
EDIT: I've now switched to using the XCode built-in XCTest system and have found that TVRSMonitor on Github provides a dead easy way to use semaphores to wait for async operations to complete.
For example:
- (void)testLogin {
TRVSMonitor *monitor = [TRVSMonitor monitor];
__block NSString *theToken;
[[Server instance] loginWithUsername:@"foo" password:@"bar"
success:^(NSString *token) {
theToken = token;
[monitor signal];
}
failure:^(NSError *error) {
[monitor signal];
}];
[monitor wait];
XCTAssert(theToken, @"Getting token");
}
I ran into the same question and found a different solution that works for me.
I use the "old school" approach for turning async operations into a sync flow by using a semaphore as follows:
// create the object that will perform an async operation
MyConnection *conn = [MyConnection new];
STAssertNotNil (conn, @"MyConnection init failed");
// create the semaphore and lock it once before we start
// the async operation
NSConditionLock *tl = [NSConditionLock new];
self.theLock = tl;
[tl release];
// start the async operation
self.testState = 0;
[conn doItAsyncWithDelegate:self];
// now lock the semaphore - which will block this thread until
// [self.theLock unlockWithCondition:1] gets invoked
[self.theLock lockWhenCondition:1];
// make sure the async callback did in fact happen by
// checking whether it modified a variable
STAssertTrue (self.testState != 0, @"delegate did not get called");
// we're done
[self.theLock release]; self.theLock = nil;
[conn release];
Make sure to invoke
[self.theLock unlockWithCondition:1];
In the delegate(s) then.
这篇关于如何单元测试异步API的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!