objective-c - Objective-C - 单元测试 dispatch_async block ?

标签 objective-c unit-testing dispatch-async

我阅读了其他针对此问题提出解决方案的帖子。但是,他们的解决方案需要将 hacky 代码添加到我的应用程序中才能对其进行测试。对我来说,干净的代码比单元测试更重要。

我经常在我的应用程序中使用 dispatch_async,但我在对其进行单元测试时遇到了问题。问题是 block 在我的测试完成后执行,因为它在主队列上异步运行。有没有办法以某种方式等到 block 被执行然后继续测试。

我不想仅仅因为单元测试而将完成传递给 block

- (viod)viewDidLoad
{
   [super viewDidLoad];

   // Test passes on this
   [self.serviceClient fetchDataForUserId:self.userId];


   // Test fails on this because it's asynchronous
   dispatch_async(dispatch_get_main_queue(), ^{
      [self.serviceClient fetchDataForUserId:self.userId];
   });
}

- (void)testShouldFetchUserDataUsingCorrectId
{
   static NSString *userId = @"sdfsdfsdfsdf";
   self.viewController.userId = userId;
   self.viewController.serviceClient = [[OCMockObject niceMockForClass:[ServiceClient class]];

   [[(OCMockObject *)self.viewController.serviceClient expect] fetchDataForUserId:userId];
   [self.viewController view]; 
   [(OCMockObject *)self.viewController.serviceClient verify];
}

最佳答案

短暂运行主循环以让它调用异步 block :

- (void)testShouldFetchUserDataUsingCorrectId {
   static NSString *userId = @"sdfsdfsdfsdf";
   self.viewController.userId = userId;
   self.viewController.serviceClient = [[OCMockObject niceMockForClass:[ServiceClient class]];

   [[(OCMockObject *)self.viewController.serviceClient expect] fetchDataForUserId:userId];
   [self.viewController view];
   [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
   [(OCMockObject *)self.viewController.serviceClient verify];
}

我想这可能会在负载很重的系统上失败,或者如果主线程上有一堆其他东西(计时器或其他 block )。如果是这种情况,您需要运行运行循环更长的时间(这会减慢您的测试用例),或者重复运行它直到满足模拟对象的期望或达到超时(这需要向模拟对象添加一个方法来询问其期望是否已达到)。

关于objective-c - Objective-C - 单元测试 dispatch_async block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12463733/

相关文章:

ios - UITabBarController setSelectedIndex 性能低下

ios - swift 3.0 : delay of less than a second

ios 核心数据 : make sure object is deleted from data source

ios - 从 NSDate 获取百分之一秒的差异

java - 模拟 Java 枚举以添加一个值来测试失败案例

unit-testing - 模拟 Microsoft Application Insights API

objective-c - 为什么 RunLoop 不会阻止整个线程执行?

ios - UITextView - 最大换行符

unit-testing - Delphi DunitX FMX GUI 记录器