如何使用逻辑测试对 iPhone Nib 进行单元测试?

发布于 2024-09-09 07:45:25 字数 593 浏览 8 评论 0原文

单元测试视图控制器似乎是 iPhone 开发中非常重要的一部分(请参阅此文章)。然而,这需要从笔尖初始化控制器,我发现这在逻辑测试中不可能正确完成。

在逻辑测试中从捆绑包加载资源(请参阅此问题)效果很好。甚至加载 Nibs 也是可能的

    UntitledViewController* controller = [[UntitledViewController alloc]initWithNibName:nil bundle:[NSBundle bundleForClass:[self class]]];

:但是,只有当笔尖仅包含 UIView 时,它才有效。其他视图(我尝试了 UITableView 和 UISwitch)导致 otest 失败,代码为 138。

是否可以使用逻辑测试来测试我的 Nib,如果可以,如何进行?

Unit Testing View Controllers seems to be very important part of iPhone Development (see this Article). This, however, requires initializing the Controllers from a Nib, which I found impossible to do properly in a logical test.

Loading Resources from a Bundle (see this Question) in a logical test works fine. Even loading Nibs is possible like this:

    UntitledViewController* controller = [[UntitledViewController alloc]initWithNibName:nil bundle:[NSBundle bundleForClass:[self class]]];

. It, however, only works as long as the nib only containts UIViews. Other views (I tried UITableView and UISwitch) result in otest failing with code 138.

Is it possible to test my Nibs using logical tests, and if so, how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猫瑾少女 2024-09-16 07:45:25

这取决于您要测试的内容。如果您想验证您的绑定设置是否正确,请阅读 Chris Hanson 关于对 Cocoa 接口进行单元测试的文章< /a>.我个人认为这是矫枉过正,并导致测试代码激增,而这些代码并不是很有用。但这只是我的2分钱。

如果您实际上尝试在测试中与这些界面元素进行交互,您最终会遇到很多测试错误,正如您所发现的,特别是对于 UIActionSheets 和 UITableViews。

但您的目标应该是对控制器的行为进行单元测试,而不是苹果 UI 对象的行为。我发现最有效的是使用 OCMock 来模拟 UI 元素并验证控制器是否对它们进行预期的调用。这里有几个例子:

  -(void)testClickingAButtonHidesAView {
     //setup
     id mockViewToHide = [OCMockObject mockForClass:[UIView class]];
     [[mockViewToHide expect] setHidden:YES];
     [controller setSomeView:mockViewToHide];

     // hideButtonClicked is an IBAction that is the hide button's target
     [controller hideButtonClicked];
     [mockViewToHide verify];
  }

  -(void)testActionSheetPublishClick {
     // ModelManager is the controller's dependency, which publishes Items
     id mockModelManager = [OCMockObject mockForClass:[ModelManager class]];
     [controller setModelManager:mockModelManager];

     // this doesn't really need to be mocked, but it's a convenient way to create
     // a reference you can validate in expect:
     id mockItem = [OCMockObject mockForClass:[Item class]];
     [controller setCurrentItem:mockItem];

     // when the user clicks "Publish" (the first button on the action sheet), 
     // the controller should publish the current item
     [[mockModelManager expect] publishItem:mockItem];

     // stub object so I know which action sheet was clicked
     id mockPublishActionSheet = [OCMockObject mockForClass:[UIActionSheet class]];
     [controller setPublishConfirmation:mockPublishActionSheet];

     // simulate action sheet click
     [controller actionSheet:mockPublishActionSheet didDismissWithButtonIndex:0];

     [mockModelManager verify];
  }

It depends on what you're trying to test. If you want to verify that your bindings are set up correctly, read Chris Hanson's article on unit testing your Cocoa interface. I personally think this is overkill, and leads to a proliferation of test code that's not very useful. But that's just my 2 cents.

If you actually try to interact with those interface elements in your test, you'll eventaully run into lots of otest errors, as you've found, particularly with UIActionSheets and UITableViews.

But your goal should be to unit test your controller's behavior, not the behavior of apple's UI objects. What I've found works best is to use OCMock to mock the UI elements and verify that the controller makes the expected calls on them. Here are a couple of examples:

  -(void)testClickingAButtonHidesAView {
     //setup
     id mockViewToHide = [OCMockObject mockForClass:[UIView class]];
     [[mockViewToHide expect] setHidden:YES];
     [controller setSomeView:mockViewToHide];

     // hideButtonClicked is an IBAction that is the hide button's target
     [controller hideButtonClicked];
     [mockViewToHide verify];
  }

  -(void)testActionSheetPublishClick {
     // ModelManager is the controller's dependency, which publishes Items
     id mockModelManager = [OCMockObject mockForClass:[ModelManager class]];
     [controller setModelManager:mockModelManager];

     // this doesn't really need to be mocked, but it's a convenient way to create
     // a reference you can validate in expect:
     id mockItem = [OCMockObject mockForClass:[Item class]];
     [controller setCurrentItem:mockItem];

     // when the user clicks "Publish" (the first button on the action sheet), 
     // the controller should publish the current item
     [[mockModelManager expect] publishItem:mockItem];

     // stub object so I know which action sheet was clicked
     id mockPublishActionSheet = [OCMockObject mockForClass:[UIActionSheet class]];
     [controller setPublishConfirmation:mockPublishActionSheet];

     // simulate action sheet click
     [controller actionSheet:mockPublishActionSheet didDismissWithButtonIndex:0];

     [mockModelManager verify];
  }
蓦然回首 2024-09-16 07:45:25

请改用应用程序测试并驱动/检查设备上的 UI。

Use application tests instead and drive/inspect your UI on the device.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文