目标C-单元测试dispatch_async块? [英] Objective C - Unit testing dispatch_async block?

查看:113
本文介绍了目标C-单元测试dispatch_async块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了其他有关此问题的解决方案的文章.但是,他们的解决方案要求将hacky代码添加到我的应用程序中,以便能够对其进行测试.对我来说,干净的代码比单元测试更重要.

I read other posts that come up with solutions to this question. However, their solutions require hacky code to be added to my application in order to be able to test it. To me clean code is more important than unit test.

我在我的应用程序中定期使用dispatch_async,但是无法对其进行单元测试.问题在于该块在我的测试已经完成之后执行,因为它在主队列上异步运行.有没有办法以某种方式等待直到执行该块,然后继续进行测试.

I use dispatch_async in my app regularly, and I'm having trouble unit testing it. The problem is the block executes after my test is already done, since it's running asynchronously on the main queue. Is there a way to somehow wait until the block is executed and then continue with the test.

我不想仅由于单元测试而将完成传递给区块

- (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 the main loop briefly to let it call the async 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];
}

我想这可能会在负载很重的系统上失败,或者如果您在主线程上有很多其他东西(计时器或其他块).在这种情况下,您需要运行更长的运行循环(这会减慢测试用例的速度),或者重复运行它,直到满足模拟对象的期望或达到超时为止(这需要向模拟对象添加方法)查询其期望值是否得到满足.

I suppose this could fail on a heavily-loaded system, or if you have a bunch of other stuff (timers or other blocks) going on the main thread. If that's the case, you need to run the run loop longer (which slows down your test case), or run it repeatedly until the mock object's expectations have been met or a timeout is reached (which requires adding a method to the mock object to query whether its expectations have been met).

这篇关于目标C-单元测试dispatch_async块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆