UnitTests和iOS:viewDidLoad触发两次

UnitTests和iOS:viewDidLoad触发两次,ios,unit-testing,Ios,Unit Testing,我正在我的一个UIViewController上测试viewDidLoad事件 - (void)testMyView { UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; MyViewController *vc = [storyboard instantiateViewControllerWithIdentifier:MYID]; [vc

我正在我的一个UIViewController上测试viewDidLoad事件

- (void)testMyView
{
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    MyViewController *vc = [storyboard instantiateViewControllerWithIdentifier:MYID];
    [vc viewDidLoad];

    STAssertNotNil(vc, @"MyViewController should not be nil");
}
如果删除行[vc viewDidLoad];,viewDidLoad从未触发

如果我让[vc viewDidLoad];此时,viewDidLoad会触发两次

我知道视图是延迟加载的,但是我如何避免这种行为呢


是否有关于视图测试的最佳实践?

您需要访问视图才能自动加载它

您可以使用类似的方法来完成此操作,而不会产生副作用:

vc.view.hidden = NO; // Or YES if it is supposed to be hidden.

哦,然后取消对viewDidLoad的手动调用,因为不需要它。

您需要访问该视图才能自动加载它

您可以使用类似的方法来完成此操作,而不会产生副作用:

vc.view.hidden = NO; // Or YES if it is supposed to be hidden.

哦,然后删除对viewDidLoad的手动调用,因为不需要它。

使用[vc view]进行延迟加载

使用[vc view]进行延迟加载

调用视图控制器的视图,即:

[vc.view layoutIfNeeded]
调用视图控制器的视图,即:

[vc.view layoutIfNeeded]
读我的便条

假设我们有以下视图控制器

class ListController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .white
  }
}
了解viewDidLoad

func testSetup() {
  let controller = ListController()
  let _ = controller.view
}
我们知道第一次创建视图时调用viewDidLoad。因此,在单元测试中,如果使用viewDidLoad触发,您将落入陷阱

func testSetup() {
  let controller = ListController()
  controller.viewDidLoad()
}
为什么调用viewDidLoad两次

它在测试中调用一次 在viewDidLoad方法中,您访问第一次创建的视图,因此它将再次触发viewDidLoad

正确的方法

最好的做法不是自己触发事件,而是做一些事情让事件发生。在单元测试中,我们只访问视图来触发viewDidLoad

func testSetup() {
  let controller = ListController()
  let _ = controller.view
}
读我的便条

假设我们有以下视图控制器

class ListController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .white
  }
}
了解viewDidLoad

func testSetup() {
  let controller = ListController()
  let _ = controller.view
}
我们知道第一次创建视图时调用viewDidLoad。因此,在单元测试中,如果使用viewDidLoad触发,您将落入陷阱

func testSetup() {
  let controller = ListController()
  controller.viewDidLoad()
}
为什么调用viewDidLoad两次

它在测试中调用一次 在viewDidLoad方法中,您访问第一次创建的视图,因此它将再次触发viewDidLoad

正确的方法

最好的做法不是自己触发事件,而是做一些事情让事件发生。在单元测试中,我们只访问视图来触发viewDidLoad

func testSetup() {
  let controller = ListController()
  let _ = controller.view
}

只能使用以下调用执行viewDidLoad一次:

_ = vc.view

只能使用以下调用执行viewDidLoad一次:

_ = vc.view

使用ViewDidDisplay而不是viewDidLoad…您需要调用–loadView方法而不是–viewDidLoad。。。它不会被调用两次。嗯,这是我第一次尝试,但它不起作用。vc.view.hidden=否;是的。-loadView用于通过编程创建的视图控制器,而不是nibs中的。请使用ViewDidDisplay而不是viewDidLoad…您需要调用–loadView方法而不是–viewDidLoad。。。它不会被调用两次。嗯,这是我第一次尝试,但它不起作用。vc.view.hidden=否;完成了技巧。-loadView用于以编程方式创建的视图控制器,而不是来自nibs.voidvc.view的控制器;也可以,您不需要访问.view上的任何属性。访问.view将加载views.voidvc.view;也可以,您不需要访问.view上的任何属性。访问。视图将加载视图。