Objective C - 单元测试dispatch_async块?

ary*_*axt 15 unit-testing objective-c dispatch-async

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

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

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

- (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];
}
Run Code Online (Sandbox Code Playgroud)

rob*_*off 41

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

- (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];
}
Run Code Online (Sandbox Code Playgroud)

我想这可能会在一个负载很重的系统上失败,或者如果你在主线程上有一堆其他东西(定时器或其他块).如果是这样的话,则需要更长的运行运行循环(这会降低你的测试用例),或直至模拟对象的期望已经达到或达到超时反复运行(需要添加一个方法来模拟对象查询是否满足其期望).


Jus*_*Sid 10

将执行包装到a中dispatch_group,然后等待组完成所有已调度的块的执行dispatch_group_wait().