简体   繁体   English

xctest-如何测试按钮上是否加载了新视图

[英]xctest - how to test if a new view loads on a button press

Just started xcode 5 and xctest. 刚刚启动xcode 5和xctest。 How do I test that a view loads on button press. 如何测试按下按钮时加载的视图。 I have programatically added method that gets called when the rightBarButtonItem is clicked 我以编程方式添加了单击rightBarButtonItem时会调用的方法

action:@selector(onSettingsButton)

and in onSettingsButton 并在onSettingsButton中

-(void) onSettingsButton{
    SettingsViewController *svc = [[SettingsViewController alloc] init];
    [self.navigationController pushViewController:svc animated:YES];
}

How to write xctest to ensure SettingsViewController brings up the Settings view? 如何编写xctest以确保SettingsViewController调出Settings视图? Thank you. 谢谢。

You need an interaction test — that is, a test that checks interactions between objects. 您需要一个交互测试,即检查对象之间交互的测试。 In this case, you want to test that -pushViewController:animated: is called on the navigation controller with a SettingsViewController . 在这种情况下,您想测试是否使用SettingsViewController在导航控制器上调用了-pushViewController:animated: So we want to put a mock object into self.navigationController which we can ask, "Were you called as expected?" 因此,我们想将一个模拟对象放入self.navigationController ,我们可以问它:“您是否如预期那样被调用?”

I'll assume a simple name for the class: MyView. 我为该类假定一个简单的名称:MyView。

The way I'd do this by hand is to Subclass and Override navigationController . 我手动执行此操作的方法是Subclass和Override navigationController So in my test code, I'd do something like this: 因此,在我的测试代码中,我将执行以下操作:

@interface TestableMyView : MyView
@property (nonatomic, strong) id mockNavigationController;
@end

@implementation TestableMyView

- (UINavigationController *)navigationController
{
    return mockNavigationController;
}

@end

Now instead of creating a MyView, the test will create a TestableMyView and set its mockNavigationController property. 现在,代替创建MyView,该测试将创建TestableMyView并设置其mockNavigationController属性。

This mock can be anything, as long as it responds to -pushViewController:animated: and records the arguments. 只要响应-pushViewController:animated:并记录参数,该模拟就可以是任何东西。 Here's a simple example, by hand: 手工举一个简单的例子:

@interface MockNavigationController : NSObject
@property (nonatomic) int pushViewControllerCount;
@property (nonatomic, strong) UIViewController *pushedViewController;
@property (nonatomic) BOOL wasPushViewControllerAnimated;
@end

@implementation MockNavigationController

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    self.pushViewControllerCount += 1;
    self.pushedViewController = viewController;
    self.wasPushViewControllerAnimated = animated;
}

@end

Finally, here's a test: 最后,这是一个测试:

- (void)testOnSettingsButton_ShouldPushSettingsViewController
{
    // given
    MockNavigationController *mockNav = [[MockNavigationController alloc] init];
    TestableMyView *sut = [[TestableMyView alloc] init];
    sut.mockNavigationController = mockNav;

    // when
    [sut onSettingsButton];

    // then
    XCTAssertEquals(1, mockNav.pushViewControllerCount);
    XCTAssertTrue([mockNav.pushedViewController isKindOfClass:[SettingsViewController class]]);
}

These things can be simplified by using mock object frameworks such as OCMock, OCMockito, or Kiwi's mocking. 这些事情可以通过使用模拟对象框架(例如OCMock,OCMockito或Kiwi的模拟)来简化。 But I think it helps to start by hand first, so that you understand the concepts. 但是,我认为先开始手工学习会有所帮助,这样您才能理解这些概念。 Then choose the tools that help. 然后选择有帮助的工具。 And if you know how to do it by hand, you'll never say, "Mocking framework X doesn't do what I need! I'm stuck!" 而且,如果您知道如何手动操作,您永远也不会说:“模拟框架X不能满足我的需求!我被困住了!”

Found one way. 找到了一种方法。 Maybe there are others .. 也许还有其他..

- (void)testSettingsViewShowsWhenSettingsButtonIsClicked{
    [self.tipViewController onSettingsButton];
    id temp = self.tipViewController.navigationController.visibleViewController;
    XCTAssertEqual([temp class], [SettingsViewController class], @"Current controller should be Settings view controller");
}

First call the onSettingsButton, which is the same as clicking the button, but not really. 首先调用onSettingsButton,它与单击按钮相同,但实际上不是。 Maybe it's okay for this simple test case? 对于这个简单的测试用例也许还可以吗? How to simulate the actual press? 如何模拟实际印刷机?

Then get the current view from the tipviewcontoller which is the rootview of the app and check that it is a SettingsViewController. 然后从tipviewcontoller(它是应用程序的根视图)获取当前视图,并检查它是否是SettingsViewController。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM