在尝试将TDD应用于异步代码时,我发现在部署目标中使用的相同代码在测试目标中不起作用。 我发现使用CLLocationManager的问题的一个例子是:
- (void)testReceivingLocation
{
locationManager = [[CLLocationManager alloc] init];
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.delegate = self;
locationManager.pausesLocationUpdatesAutomatically = NO;
if ([CLLocationManager locationServicesEnabled])
{
[locationManager startUpdatingLocation];
}
startLocation = nil;
NSDate *until = [NSDate dateWithTimeIntervalSinceNow:10];
while ([until timeIntervalSinceNow] > 0)
{
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:until];
}
XCTAssert(alreadyReceivedLocation, @"Location wasn't received.");
}
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
alreadyReceivedLocation = true;
// Never actually get there.
}
可能是什么问题?
答案 0 :(得分:0)
你应该详细说明[SomeClass performActionWithAsyncResponse]如何完成它的工作。
假设在主队列的块中调用了completionWithResult,这将无效,因为线程在测试方法完成后结束。生产中并非如此,因为应用程序一直在运行。
通常我使用这样的代码来等待在测试中回调主队列的异步调用。
NSDate *until = [NSDate dateWithTimeIntervalSinceNow:30];
while ([loopUntil timeIntervalSinceNow] > 0)
{
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:until];
}
您还可以使用一个条件来停止while循环,该条件指示异步工作是否已完成,例如使用测试的属性。
有关异步测试模式的更多信息,请参阅此帖子: Pattern for unit testing async queue that calls main queue on completion