简体   繁体   English

单元测试(Kiwi):在调用loadView和viewDidLoad之后,属性在测试中总是为零

[英]Unit testing (Kiwi): Property is always nil in test after loadView and viewDidLoad are called

I am writing a unit test template project for my own reference's sake. 我正在编写一个单元测试模板项目,供我自己参考。 This includes template code for all the basic tasks, such as verifying that a UILabel's text property is set as expected after viewDidLoad. 这包括所有基本任务的模板代码,例如验证在viewDidLoad之后UILabel的text属性是否按预期设置。

I have a storyboard with a ViewController with one UILabel. 我有一个带有一个UILabel的ViewController的故事板。 In viewDidLoad I set it's text. 在viewDidLoad中我设置了它的文本。 The test then asserts whether or not the text has been set as expected, but for some reason, the UILabel is always nil. 然后测试断言文本是否按预期设置,但由于某种原因,UILabel总是为零。 Everything works as expected (thank god) when I run the app; 当我运行应用程序时,一切都按预期工作(感谢上帝); a white view is shown with a label with the expected text. 显示带有预期文本的标签的白色视图。

I am using Kiwi as my test framework and Xcode v4.5. 我使用Kiwi作为我的测试框架和Xcode v4.5。

Here's some code: 这是一些代码:

ViewController.h: ViewController.h:

@property (strong, nonatomic) IBOutlet UILabel *myLabel;

ViewController.m: ViewController.m:

- (void)viewDidLoad {
    myLabel.text = @"test";
}

ViewControllerTests.m: ViewControllerTests.m:

ViewController *vc = [[ViewController alloc] init];

// create view in memory by calling view's getter
[vc view];

// set myLabel.text to "test"
[vc viewDidLoad];

[vc.myLabel shouldNotBeNil];
[[vc.myLabel.text should] equal:@"test"];

The above test fails, telling me that myLabel is nil. 上面的测试失败了,告诉我myLabel是零。

This StackOverflow answer states that calling loadView will create the view hierarchy in memory and thereby prepare any subviews for use. 此StackOverflow应答表明调用loadView将在内存中创建视图层次结构,从而准备任何子视图以供使用。 According to the documentation , simply calling a ViewController view's getter will call loadView for you and create all views. 根据文档 ,只需调用ViewController视图的getter就会为您调用loadView并创建所有视图。 Therefore, I find it extremely odd that myLabel = nil at the time of testing. 因此,我发现测试时myLabel = nil非常奇怪。

In your view controller, you are not assigning a value to self.myLabel . 在视图控制器中,您没有为self.myLabel分配值。

self.myLabel = [[UILabel alloc] init];

This means self.myLabel has a nil value, so the following sequence occurs: [self myLabel] returns nil, [nil setText:@"test"] does nothing. 这意味着self.myLabel的值为nil,因此会出现以下序列: [self myLabel]返回nil, [nil setText:@"test"]不执行任何操作。 All of this is standard behavior. 所有这些都是标准行为。

When you load the view controller from the nib or storyboard, the label is assigned according to how the outlets are drawn in IB, but calling ViewController *vc = [[ViewController alloc] init] does not loading the nib or storyboard. 从nib或storyboard加载视图控制器时,将根据在IB中绘制插座的方式分配标签,但调用ViewController *vc = [[ViewController alloc] init]不会加载nib或storyboard。


Update 更新

After re-reading my post, I think I left the wrong impression. 重新阅读我的帖子后,我想我留下了错误的印象。

You need to load from a nib or storyboard, not add self.myLabel = [[UILabel alloc] init] . 您需要从笔尖或故事板加载,而不是添加self.myLabel = [[UILabel alloc] init]

To load from a nib, use -initWithNibName:bundle: instead of -init . 要从nib加载,请使用-initWithNibName:bundle:而不是-init To load from a storyboard, first load the storyboard use +[UIStoryboard storyboardWithName:bundle:] , then load the view controller from the storyboard using -[UIStoryboard instantiateViewControllerWithIdentifier:] . 要从故事板加载,首先加载故事板使用+[UIStoryboard storyboardWithName:bundle:] ,然后使用-[UIStoryboard instantiateViewControllerWithIdentifier:]从故事板加载视图控制器。

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

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