2016-06-23 30 views
1

如果我dispatch_async这样上队列块:在单元测试中,执行队列中通过与dispatch_asyc块

-(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? 
} 

===澄清===

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

+0

什么正试图测试:网络请求或后台任务还是别的什么结果呢? 如果您需要测试异步调用,则存根'''self.service fetchData'立即调用并回调,然后您可以在这里使用''''waitForExpectationsWithTimeout'''解决方案。这不会花费很长时间。 – Konstantin

+0

@Konstantin,它可能是任何东西,网络请求,后台任务等。这不是我的问题的重点。我只是想知道如何手动让队列执行块。这是我主要关心的问题。 –

+0

我不认为这是可能的,除非您在测试函数中创建队列并将其传递。这可能不是你想要的。 – Code

回答

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也没必要)

+0

那我在哪里做断言呢?你的意思是在测试函数dispatch_sync(queue,^ {// assertion here?});'它同步调度执行被调用的函数中的'dispatch_async'调用中入队的任务,然后在该块中排队声明部分? –

+0

@ Leem.fin你可以在'dispatch_sync'之后执行。 – Code

+0

,但它是否在测试中的dispatch_sync(queue,^ {});'的目的是等待被测试函数中入队任务的执行?如果答案是YES,那么我们可以这样认为'dispatch_sync(queue,^ {ASSERT()})''会将'ASSERT()'作为下一个执行任务来排队,所以,我实际上可以在内部声明像我在之前的评论中所做的那样? –

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

希望这有助于

+0

这就是为什么我要求如何手动执行块的原因,因为我不想使用'waitForExpectationsWithTimeout',因为在不同的机器上,等待时间可能会不同,所以设置等待时间看起来很糟糕。我想手动让队列执行块,然后检查结果,就像我为主队列做的那样。 –

+0

请阅读文档“我不喜欢OCMock提供的waitForExpectationsWithTimeout:Timeout”这个评论是绝对不正确的。 OCMock没有提供这种方法,Apple提供的'XCTestExpectation'类。 – iSashok

+0

我会更新它,无论如何,我不喜欢等待超时测试的方式,原因是一样的,等待时间在不同的机器上是不可预测的。 –

相关问题