2017-10-11 106 views
2

简化了代码结构,我有一个UIViewControllerviewDidLoad(),它调用一个方法,使用DispatchQueue.main.async()等待主线程执行代码。这个测试是否稳健?我可以在单元测试中使用DispatchQueue.main.async()吗?

viewDidLoad() { 
    method() 
} 

method() { 
    ... 
    DispatchQueue.main.async() { 
     ...some code... 
    } 
} 

我的测试还需要等待主线程调用XCTAssertEqual之前。

func testSuccessRequest() { 
     let exp = expectation(description: "labelText") 
     let vc = ViewController.init() 
     vc.request = SuccessRequest.init() 
     vc.loadViewIfNeeded() 

     DispatchQueue.main.async() { 
      XCTAssertEqual(vc.label.text, "success") 
      exp.fulfill() 
     } 

     waitForExpectations(timeout: 40, handler: nil) 
} 

该测试是否健壮?或者我可以在异步之前调用断言代码吗?

回答

0

由于()方法是异步所以在测试如果调用

DispatchQueue.main.async() { 
      XCTAssertEqual(vc.label.text, "success") 
      exp.fulfill() 
     } 

右后vc.loadViewIfNeeded()你不能保证测试用例预期将异步方法之前得到充分的填充()调用被完成。 由于这两个调用 - 上述方法()& - 都是异步的。

但是你可以做的是 - 有些时候像下面后,足以满足测试用例的期望:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
      XCTAssertEqual(vc.label.text, "success") 
      [expectation fulfill]; 
      }); 

waitForExpectations(timeout: 40, handler: nil) 

这是你可以测试异步方法是使用GCD的一种方式。希望能帮助到你。

编辑: 虽然上述策略可以让你等待2秒。在这种情况下,我们可以实施更好的方法。

我们可以帮助XCTKVOExpectation和XCTWaiter类在XCTest框架中使用。下面是关于他们的简要描述:

  • XCTKVOExpectation 客旅的期望是完全观察到 对象由“的keyPath”充满
  • XCTWaiter 提供当期望超时比较更具描述性的返回值到正常waitForExpectations(超时:,处理程序:),它只是抛出错误。

现在你的测试用例看起来像。

func testSuccessRequest() {    
     let promise = XCTKVOExpectation(keyPath: "text", object: vc.label, 
               expectedValue: "success") 
     let vc = ViewController.init() 
     vc.request = SuccessRequest.init() 
     vc.loadViewIfNeeded() 
     let result = XCTWaiter().wait(for: [promise], timeout: 40) 
     XCTAssertTrue(result == .completed) 
    }  

这里,KVO exp。是在标签的“文本”属性上创建的,然后视图加载了异步调用,然后测试用例在超时之前等待一段时间。然后你可以断言来自XCTWaiter的返回值。

希望它有帮助。

+0

嗨,所以你使用了2秒的延迟,对不对?但这不仅仅是一种解决方法吗?我宁愿不必通过设置随机延迟值来减慢测试速度。 – aneuryzm

+0

谢谢。你的解决方案是有效的,在我看来,我可以在处理异步线程时定期使用它。我想知道:这个问题有多普遍?看来你必须想一点。但是UILabel异步更新并不常见?换句话说:你给我的解决方案有多普遍? – aneuryzm

+0

这是GCD函数或KVO不返回回调的常见问题。这是它有用的场景。我真的必须改进我的前期。我们故意拖延的解决方案。 – manismku

相关问题