Тестирование существования представленного ViewController с использованием Cedar
Я пытаюсь проверить, существует ли представленный контроллер представления, когда я автоматизировал касание ячейки строки таблицы. Когда я пытаюсь проверить, принадлежит ли контроллер представленный ViewController к заданному типу класса, это всегда приводит к нулю. Я предполагаю, что новый представленный контроллер представления переходит в представленный контроллер представления, и поэтому [controller представил ViewViewController] равен нулю.
Я использую каркас тестирования Cedar BDD. Я установил библиотеки PivotalCore, чтобы обеспечить автоматизированную функцию "касания".
Вот код Spec:
#import <Cedar-iOS/Cedar-iOS.h>
#import "UITableViewCell+Spec.h"
#import "FMNavigatorViewController.h"
using namespace Cedar::Matchers;
using namespace Cedar::Doubles;
SPEC_BEGIN(FMNavigatorViewControllerSpec)
describe(@"FMNavigatorViewController", ^{
__block UINavigationController *nav;
__block FMNavigatorViewController *controller;
beforeEach(^{
FSHandle *documents = [FSHandle handleAtUrl:[[BasicFileManager sharedManager] documentsUrl] isDirectory:YES];
// @todo Remove all files from Recent Files and Local Files.
// Remove all configured remote connections.
NSArray *contents = [[BasicFileManager sharedManager] contentsOfDirectoryAtURL:documents.url];
for (NSURL *url in contents) {
if (! [url.lastPathComponent isEqualToString:@"Local Files"] && ! [url.lastPathComponent isEqualToString:@"Recent Files"]) {
NSLog(@"WARNING: Deleting Manager: %@", url.lastPathComponent);
FileManager *manager = [FileManager fileManagerWithName:url.lastPathComponent];
[manager deleteFileManager];
}
}
// Create view.
controller = [[FMNavigatorViewController alloc] initWithDirectory:documents];
nav = [[UINavigationController alloc] initWithRootViewController:controller];
// Initiates view lifecycle. Accessing the 'view' will automatically
// create it.
nav.view should_not be_nil;
// Doesn't get called unless properly added to a heirarchy -- which I
// haven't found the correct process for yet.
[controller viewWillAppear:NO];
});
it(@"should contain Local and Recent Files with no other connections", ^{
controller should be_instance_of([FMNavigatorViewController class]);
// Local and Remote Connection Groups
[controller.tableView.dataSource numberOfSectionsInTableView:controller.tableView] should equal(2);
// Recent Files and Local Files
[controller.tableView.dataSource tableView:controller.tableView numberOfRowsInSection:0] should equal(2);
// Enforce order: Local Files then Recent Files.
[[[controller.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]] textLabel] text] should equal(@"Local Files");
[[[controller.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]] textLabel] text] should equal(@"Recent Files");
// The second group should have one row with description.
[controller.tableView.dataSource tableView:controller.tableView numberOfRowsInSection:1] should equal(1);
[[[controller.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]] textLabel] text] should equal(NSLocalizedString(@"CreateRemoteConnection", @""));
});
it(@"should display the FM wizard view", ^{
[[controller.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]] tap];
controller.presentedViewController should_not be_nil;
//[nav presentedViewController] should be_instance_of([UINavigationController class]);
//[controller presentedViewController] should be_instance_of([UINavigationController class]);
});
});
SPEC_END
Самые последние тесты содержат соответствующий код. Мой вопрос: мне нужно подождать секунду или две, прежде чем тестировать, если представленный ViewController не ноль? Если да, то как мне это сделать?
Вот код, который должен выполняться после касания ячейки:
FMWizardViewController *controller = [FMWizardViewController new];
[controller setDelegate:self];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:controller];
nav.navigationBar.tintColor = UIColorFromRGB(BNAV_TINT_COLOR);
[self presentViewController:nav animated:YES completion:nil];
Я дважды проверил, чтобы убедиться, что этот код действительно запускается после нажатия на ячейку; оно делает.
Спасибо!
1 ответ
С помощью группы обсуждения кедра Google ( https://groups.google.com/forum/) мне удалось это выяснить.
То, что должно было случиться, было:
- Основной цикл выполнения необходимо было продвинуть для того, чтобы был представлен экземпляр ViewViewController и привязан к соответствующему контроллеру представления
- Необходимо было создать всю иерархию представления (окно, контроллер навигации, FMNavigationController)
#import <Cedar-iOS/Cedar-iOS.h>
#import "UITableViewCell+Spec.h"
#import "FMNavigatorViewController.h"
// << -- Add this
#define tickRunLoop (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.01, false))
using namespace Cedar::Matchers;
using namespace Cedar::Doubles;
SPEC_BEGIN(FMNavigatorViewControllerSpec)
describe(@"FMNavigatorViewController", ^{
__block UIWindow *window; // <<-- and this,
__block UINavigationController *nav;
__block FMNavigatorViewController *controller;
beforeEach(^{
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
FSHandle *documents = [FSHandle handleAtUrl:[[BasicFileManager sharedManager] documentsUrl] isDirectory:YES];
// @todo Remove all files from Recent Files and Local Files.
// Remove all configured remote connections.
NSArray *contents = [[BasicFileManager sharedManager] contentsOfDirectoryAtURL:documents.url];
for (NSURL *url in contents) {
if (! [url.lastPathComponent isEqualToString:@"Local Files"] && ! [url.lastPathComponent isEqualToString:@"Recent Files"]) {
NSLog(@"WARNING: Deleting Manager: %@", url.lastPathComponent);
FileManager *manager = [FileManager fileManagerWithName:url.lastPathComponent];
[manager deleteFileManager];
}
}
// Create view.
controller = [[FMNavigatorViewController alloc] initWithDirectory:documents];
nav = [[UINavigationController alloc] initWithRootViewController:controller];
window.rootViewController = nav;
[window makeKeyAndVisible];
// Initiates view lifecycle. Accessing the 'view' will automatically
// create it.
nav.view should_not be_nil;
// Doesn't get called unless properly added to a heirarchy -- which I
// haven't found the correct process for yet.
[controller viewWillAppear:NO];
});
it(@"should contain Local and Recent Files with no other connections", ^{
controller should be_instance_of([FMNavigatorViewController class]);
// Local and Remote Connection Groups
[controller.tableView.dataSource numberOfSectionsInTableView:controller.tableView] should equal(2);
// Recent Files and Local Files
[controller.tableView.dataSource tableView:controller.tableView numberOfRowsInSection:0] should equal(2);
// Enforce order: Local Files then Recent Files.
[[[controller.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]] textLabel] text] should equal(@"Local Files");
[[[controller.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]] textLabel] text] should equal(@"Recent Files");
// The second group should have one row with description.
[controller.tableView.dataSource tableView:controller.tableView numberOfRowsInSection:1] should equal(1);
[[[controller.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]] textLabel] text] should equal(NSLocalizedString(@"CreateRemoteConnection", @""));
});
it(@"should display the FM wizard view", ^{
// Sanity to ensure we are tapping the right cell.
[[controller.tableView.visibleCells[2] textLabel] text] should equal(NSLocalizedString(@"CreateRemoteConnection", @""));
[controller.tableView.visibleCells[2] tap];
tickRunLoop; // <<-- and this.
controller.presentedViewController should_not be_nil;
controller.presentedViewController should be_instance_of([UINavigationController class]);
});
});
SPEC_END
Все тесты проходят сейчас.
Один из сопровождающих сказал, что проблема, скорее всего, связана с некоторыми внутренними изменениями, внесенными в iOS 8; где он не связывает значение представленного ViewController, как только вызывается presentViewController: анимированный: завершение:. Это должно быть решено в будущем.
Я надеюсь, что это помогает кому-то!
ОБНОВИТЬ
Я забыл добавить, что продвижение цикла выполнения не лучшая практика. Это следует рассматривать как пробел, пока проблема не будет устранена.