在单元测试中,执行队列中传递的块 dispatch_asyc

In unit test, execute the block passed in queue with dispatch_asyc

如果我 dispatch_asyncmain 队列上的一个块是这样的:

-(void) myTask {
  dispatch_async(dispatch_get_main_queue(), ^{
      [self.service fetchData];
   });
}

在单元测试中,我可以通过手动运行主循环来执行主队列中传递的块,如下所示:

-(void)testMyTask{
  // call function under test
  [myObj myTask];
  // run the main loop manually!
  [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
  // now I can verify the function 'fetchData' in block is called
  ...
}

现在,我有另一个类似的函数,它将块分派到顺序队列 ,而不是 主队列:

-(void) myTask2 {
  dispatch_async(dispatch_queue_create("my.sequential.queue", NULL), ^{
      [self.service fetchData];
   });
}

在单元测试中,我现在如何手动执行块?

-(void)testMyTask2{
  // call function under test
  [myObj myTask2];
  // How to manually execute the block now?
}

===澄清===

之所以要手动执行是因为我不喜欢任何Wait-For-Timeout的方式做测试。因为等待时间取决于 CPU 速度,所以在不同的机器上可能会有所不同。我想手动执行传递给队列的块(与我对主队列测试用例所做的方式相同),然后验证结果。

要在异步块中执行测试,请使用 XCTestExpectation class

-(void) myTask2 {
  XCTestExpectation *expectation = [self expectationWithDescription:@"catch is called"];
  dispatch_async(dispatch_queue_create("my.sequetial.queue", NULL), ^{
      [self.serviceClient fetchDataForUserId:self.userId];
      [expectation fulfill];
   });

   [self waitForExpectationsWithTimeout:Timeout handler:^(NSError *error) {
        //check that your NSError nil or not
    }];
}

希望对您有所帮助

您可以在测试函数中创建队列。

-(void) myTask2:(dispatch_queue_t*)queue {
    dispatch_async(*queue, ^{
        [self.service fetchData];
    });
}

-(void)testMyTask2{
    dispatch_queue_t queue = dispatch_queue_create("my.sequential.queue", NULL);
    [myObj myTask2:&queue];

    dispatch_sync(queue, ^{
    });
}

(刚发现不需要currentRunLoop