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

时间:2016-06-23 12:56:39

标签: ios objective-c unit-testing grand-central-dispatch ocmock

如果我dispatch_async阻止队列,请执行以下操作:

-(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速度,所以在不同的机器上可能会有所不同。我想手动执行传递给队列的块(与我对主队列测试用例的操作方式相同),然后验证结果。

2 个答案:

答案 0 :(得分:1)

您可以在测试功能中创建队列。

-(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不需要)

答案 1 :(得分:0)

对于异步块中的执行测试,请使用XCTestExpectation

-(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
    }];
}

希望这个帮助