如何编写用于测试视图控制器的单元测试?

时间:2014-11-19 09:28:49

标签: ios objective-c xctest ocmock ui-testing

我们正在尝试编写自定义单元测试,以分别测试每个视图控制器。我知道有UI自动化,KIF和其他解决方案,但是如果您看一下上面的代码,那么您会发现应该可以不使用它们。

因此,为简单起见,假设有一个简单的视图控制器,它有两个公共方法“setFirstState”和“setSecondState”。我需要测试,当视图控制器完全实例化并在屏幕上显示(通过viewDidLoad)时调用“setFirstState”方法。这是演示视图控制器:

@interface MyViewController 

  - (void)setFirstState;
  - (void)setSecondState;

@end

@implementation MyViewController

  - (void)viewDidLoad {

    [super viewDidLoad];

    [self setFirstState];
  }

@end

因此,测试setFirstState调用的单元测试可能看起来像(使用XCTest和OCMock):

- (void)test_viewDidLoad_CallsMyMethod {

  MyViewController *viewContoller = [[MyViewController alloc] init];

  id mock = [OCMockObject partialMockForObject:viewContoller];
  [[mock expect] showLogin];

  [UIApplication sharedApplication].keyWindow.rootViewController = (MyViewController *)mock;

  [mock verify];
}

有趣的代码行是将key(在viewController上)分配给keyWindow的rootViewController。如果我们想要调用viewDidLoad,viewWillAppear方法,我们发现我们需要这样做。否则他们将不被召唤。但是,如果我们运行测试,那么模拟器就会挂起。 Xcode显示它正在运行并且仍然存在,但它不会更进一步。

我们还尝试将keyWindow的rootViewController代码行替换为“[mock viewDidLoad]”,仅用于模拟和测试viewDidLoad,但它也会挂起。因此,它看起来像部分模拟打破了出现的视图控制器的内部流程。

如果我们将删除mock并将视图控制器直接分配给keyWindow的rootViewController,那么它可以工作,我们可以测试所有其他的东西。但是,也许有人知道我们如何解决这个问题?

更新忘记提及我们使用Xib而不是Storyboard,因此我们系统中的每个组件都松散耦合。

1 个答案:

答案 0 :(得分:0)

事实证明,NewRelic库正在打破OCMock :)。因此,一切都在评论之后起作用:

//[NewRelicAgent startWithApplicationToken:@"token"];