我正面临XCTestCase对象中异步操作的问题。
我从一系列
expectation-waitForExpectation
,有时将期望实例作为方法参数传递,以使其由异步操作完成块实现。
现在我改变了方法,因为我看不到以前编写的糟糕代码,我尝试了这种方式:
- (void)testThatItGoesToTheRightSport
{
if (! appDelegateInstance.firstTimeLoaded)
{
[self __waitForLoadingAppAndDo:^(BOOL launched)
{
if (launched)
{
[self __goToLiveWithHandler:^(BOOL success) {
if (success)
{
[self __goToLiveSport:[NSNumber numberWithUnsignedInteger:kDefaultSportCode]
handler:^(BOOL success) {
if (! success)
{
XCTFail(@"Test failed");
}
}];
}
}];
}
}];
}
else
{
[self __goToLiveWithHandler:^(BOOL success) {
if (success)
{
[self __goToLiveSport:[NSNumber numberWithUnsignedInteger:kDefaultSportCode]
handler:^(BOOL success) {
if (! success)
{
XCTFail(@"Test failed");
}
}];
}
}];
}
}
具有
__waitForLoadingAppAndDo:
方法实现为
- (void)__waitForLoadingAppAndDo:(void (^)(BOOL launched))afterBlock
{
if (! afterBlock)
XCTFail(@"No afterBlock");
XCTestExpectation *dataEx = [self expectationForNotification:NOTIFICATION_HOME_LOADED
object:nil
handler:^BOOL(NSNotification *notification) {
[dataEx fulfill];
return YES;
}];
[self waitForExpectationsWithTimeout:SOCKOPT_TIMEOUT handler:^(NSError *error)
{
if (error)
{
XCTFail(@"No data received. %@", [error localizedDescription]);
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
afterBlock(YES);
});
}
}];
}
另一个
__
方法与之类似。显然,现在
testThat
方法未等待方法完成处理程序。我该如何改进它,我该如何
testThat测试
方法等待完成?是
XCTestExpectation
在路上?(不要告诉我哦)
添加:
那么,这是唯一的方法吗?
- (void)testThatItGoesToTheRightSport
{
if (! appDelegateInstance.firstTimeLoaded)
{
XCTestExpectation *waitingLoading = [self expectationWithDescription:@"loadingApp"];
[self waitForExpectationsWithTimeout:SOCKOPT_TIMEOUT handler:^(NSError *error) {
if (error)
{
XCTFail(@"After block was not called.");
}
}];
[self __waitForLoadingAppAndDo:^(BOOL launched)
{
if (launched)
{
[self __goToLiveWithHandler:^(BOOL success) {
if (success)
{
[waitingLoading fulfill];
[...]
}
}];
}
}];
添加-2
:
我试过了
__block NSError *internalError = nil;
__block XCTestExpectation *finishedTest = [self expectationWithDescription:@"finishedTest"];
dispatch_group_t asyncGroup = dispatch_group_create();
if (! appDelegateInstance.firstTimeLoaded)
{
dispatch_group_enter(asyncGroup);
[self __waitForLoadingAppAndDo:^(BOOL launched) {
if (! launched)
{
internalError = [TestUtilities notLoadedAppError];
}
dispatch_group_leave(asyncGroup);
}];
dispatch_group_enter(asyncGroup);
[self __goToLiveWithHandler:^(BOOL success) {
if (! success)
{
internalError = [NSError errorWithDomain:@"goLive"
code:-1
userInfo:@{NSLocalizedDescriptionKey : @"Errore apertura Live"}];
}
dispatch_group_leave(asyncGroup);
}];
dispatch_group_notify(asyncGroup, dispatch_get_main_queue(), ^{
[finishedTest fulfill];
});
但这些组被称为异步组,无需等待完成块。
例如:我期待着
操作1
首先开始,在
操作1
完井区块
操作2
将启动。
添加-3
:
我用了不同的方法
dispatch_semaphore
。我喜欢它,但有一件东西我会替换掉。如果我要等待信号,我会阻塞主线程,所以我必须
dispatch_async
这个
wait
命令如下:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
dispatch_semaphore_wait(loadedApp, DISPATCH_TIME_FOREVER);
dispatch_async(dispatch_get_main_queue(), ^{
[self __goToLiveWithHandler:^(BOOL success) {
if (success)
{
[...]
}
}];
});
});
有没有办法避免这种情况?