【问题标题】:Is it possible to unit test a WindowController thats initialised with a nib?是否可以对使用 nib 初始化的 WindowController 进行单元测试?
【发布时间】:2014-02-28 04:34:36
【问题描述】:

我有一个简单的 Mac OS 应用程序,它带有默认的 MainMenu.xib。在那里我有第二个偏好窗口和PreferencesWindowController。我想进行以下测试:

@implementation TestPreferencesWindow

- (void)testProtectsUserPasswordByUsingAPasswordField
{
    PreferencesWindowController *controller = [[PreferencesWindowController alloc] initWithWindowNibName:@"MainMenu"];
    XCTAssertInstanceOf([[controller passwordField] class], NSSecureTextField);
}

@end

问题是[controller passwordField] 没有初始化(因为笔尖没有加载?)所以它总是返回nil

如何告诉 nib 创建所有绑定?

当我调用[controller window] 时,会给出错误,并返回nil

Could not connect the action orderFrontStandardAboutPanel: to target of class PreferencesWindowController

为了调试,我尝试了以下方法:

NSBundle *bundle = [NSBundle mainBundle];
XCTAssertNotNil(bundle);
NSString *nibPath = [bundle pathForResource:@"MainMenu" ofType:@"nib"];
XCTAssertNotNil(nibPath); 

PreferencesWindowController *controller = [[PreferencesWindowController alloc] initWithWindowNibPath:nibPath owner:self];
NSLog(@"%@ %@", [controller window], [controller passwordField]);

但是它仍然打印(null) (null) ...

摆脱警告:

NSBundle *bundle = [NSBundle mainBundle];
XCTAssertNotNil(bundle);
NSString *nibPath = [bundle pathForResource:@"MainMenu" ofType:@"nib"];
XCTAssertNotNil(nibPath);

NSApplication *app = [NSApplication sharedApplication];
PreferencesWindowController *controller = [[PreferencesWindowController alloc] initWithWindowNibPath:nibPath owner:app];
NSLog(@"%@ %@", [controller window], [controller passwordField]);

没有更多警告,但仍然打印(null) (null) ..我觉得我越来越近了...

【问题讨论】:

  • 是否将 MainMenu.xib 添加到您的单元测试目标中?
  • 我没有想到它没有任何区别的错误。如果我故意输入一个不存在的笔尖名称,它也不会报告任何错误...
  • 好吧,如果找不到 nib,该方法应该返回 nil。
  • 主目标和测试目标在 Copy Bundle Resources 阶段都将 MainMenu.xib 显示为红色(好像该文件不存在一样)......对吗?我还应该指出,应用程序显然正确加载了窗口。
  • 嘿,Elliot,您找到解决方案了吗?我也面临同样的问题。

标签: xcode unit-testing nib xctest


【解决方案1】:

我得到了解决方案。在 .m 文件中写入以下方法,并在 .h 文件中声明为 public

MyWindowController.m 文件

- (instancetype)initWithWindowNibPath:(NSString *)nibPath {
    self = [super initWithWindowNibPath:nibPath owner:self];
    if(self)
    {
        //initialize stuff
    }
    return self;
}

MyWindowController.h 文件

- (instancetype)initWithWindowNibPath:(NSString *)nibPath;

现在编写你的代码:

NSBundle *bundle = [NSBundle mainBundle];
XCTAssertNotNil(bundle);
NSString *nibPath = [bundle pathForResource:@"MyWindowController" ofType:@"nib"];
XCTAssertNotNil(nibPath); 

MyWindowController *controller = [[MyWindowController alloc] initWithWindowNibPath:nibPath];
NSLog(@"%@ %@", [controller window], [controller passwordField]);

这对我来说很完美。

原因: 所有者值未在 initWithWindowNibPath 方法中正确设置,因此未将类的属性 NSOutlet 设置为 nib 的控件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-27
    • 2010-09-08
    • 1970-01-01
    • 2020-02-21
    • 2016-06-14
    • 1970-01-01
    • 2013-02-04
    • 2015-09-26
    相关资源
    最近更新 更多