gpt4 book ai didi

ios - 在后台线程上调用 XCTestExpectation fulfill 方法是否安全?

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:37:16 27 4
gpt4 key购买 nike

我在很多测试中都使用了 XCTestExpectation,有时(非常随机地)一些期望没有实现(尽管我确信它们应该是)。

在调查这个问题时,我注意到一些期望在主线程中实现,而一些在后台线程中实现。到目前为止,这些问题都是在后台线程中完成的。

从后台线程满足期望是否安全?我找不到任何相关的明确信息。

下面是我如何使用 XCTestExpectation 的示例:

__block XCTestExpectation *expectation = [self expectationWithDescription:@"test"];

[self doSomethingAsyncInBackgroundWithSuccess:^{
[expectation fullfill];
}];

[self waitForExpectationsWithTimeout:10.0 handler:^(NSError *error) {
expectation = nil;
if (error) {
NSLog(@"Timeout Error: %@", error);
}
}];

最佳答案

没有任何地方记录 XCTestExpectation 是线程安全的。由于没有关于此事的官方文档,您只能通过创建测试示例来猜测:

- (void)testExpectationMainThread;
{

__block XCTestExpectation *expectation = [self expectationWithDescription:@"test"];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[expectation fulfill];
});

[self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) {
NSLog(@"%@", error);
}];

}

- (void)testExpectationStartMainThreadFulfilBackgroundThread;
{

__block XCTestExpectation *expectation = [self expectationWithDescription:@"test"];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, kNilOptions), ^{
[expectation fulfill];
});

[self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) {
NSLog(@"%@", error);
}];

}

- (void)testExpectationBackgroundThread;
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, kNilOptions);

__block XCTestExpectation *expectation;


dispatch_sync(queue, ^{
expectation = [self expectationWithDescription:@"test"];
});

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), queue, ^{
[expectation fulfill];
});

[self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) {
NSLog(@"%@", error);
}];

}

这里它不会崩溃或导致问题,但是由于缺少官方文档,坚持使用相同的队列来完成可能更安全。


你真的应该将方法 stub doSomethingAsyncInBackgroundWithSuccess并为应用程序提供本地“虚拟”数据。

你的单元测试不应该依赖于网络,因为它是可变的。


您应该执行 doSomethingAsyncInBackgroundWithSuccess 的完成 block 在主线程上(或者至少提供一种在同一线程上一致回调的方法),您可以使用 GCD 轻松地做到这一点。

- (void)doSomethingAsyncInBackgroundWithSuccess:(void (^)(void))completion;
{
dispatch_async(dispatch_get_main_queue(), ^{
completion();
});
}

或者使用 NSOperationQueue mainQueue

- (void)doSomethingAsyncInBackgroundWithSuccess:(void (^)(void))completion;
{
[NSOperationQueue.mainQueue addOperationWithBlock:^{
completion();
}];
}

关于ios - 在后台线程上调用 XCTestExpectation fulfill 方法是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34748161/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com