如何对异步 API 进行单元测试? [英] How to unit test asynchronous APIs?

查看:42
本文介绍了如何对异步 API 进行单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将 Google Toolbox for Mac 安装到 Xcode 中并遵循设置单元测试的说明位于此处.

I have installed Google Toolbox for Mac into Xcode and followed the instructions to set up unit testing found here.

一切都很好,我可以在我所有的对象上测试我的同步方法绝对没问题.但是,我实际上想通过调用委托上的方法异步测试大多数复杂的 API 返回结果 - 例如,对文件下载和更新系统的调用将立即返回,然后在文件完成下载时运行 -fileDownloadDidComplete: 方法.

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?

似乎我想要 testDownload 函数,或者至少让测试框架等待" fileDownloadDidComplete: 方法运行.

It seems like I'd want to the testDownload function, or at least the test framework to 'wait' for fileDownloadDidComplete: method to run.

我现在改用 XCode 内置 XCTest 系统,发现 TVRSMonitor 在 Github 上提供了一种使用信号量等待异步操作完成的简单方法.

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.

例如:

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

确保调用

[self.theLock unlockWithCondition:1];

然后在委托中.

这篇关于如何对异步 API 进行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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