final class TabComponentViewController: UIViewController, TabComponent { let tabItem: TabItem init(title: String) { tabItem = TabItem(title: title) super.init(nibName: nil, bundle: nil) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } final class TabItemViewControllerRouterTests: XCTestCase { let tabComponent1 = TabComponentViewController(title: "1") let tabComponent2 = TabComponentViewController(title: "2") let parentViewController = UIViewController() func testNoViewControllerParentsByDetault() { let _ = TabItemViewControllerRouter(tabComponents: [tabComponent1, tabComponent2], parentViewController: parentViewController, viewHierarchyUpdater: { _ in }) XCTAssertNil(tabComponent1.parentViewController) XCTAssertNil(tabComponent2.parentViewController) } func testSelectingTabBarItemAddsViewControllerToParent() { let router = TabItemViewControllerRouter(tabComponents: [tabComponent1, tabComponent2], parentViewController: parentViewController, viewHierarchyUpdater: { _ in }) router.selectTabItem(tabComponent1.tabItem) XCTAssertEqual(tabComponent1.parentViewController, parentViewController) } func testSelectingTwoTabBarItemAddsViewControllerToParentAndRemovesPreviousController() { let router = TabItemViewControllerRouter(tabComponents: [tabComponent1, tabComponent2], parentViewController: parentViewController, viewHierarchyUpdater: { _ in }) router.selectTabItem(tabComponent1.tabItem) router.selectTabItem(tabComponent2.tabItem) XCTAssertNil(tabComponent1.parentViewController) XCTAssertEqual(tabComponent2.parentViewController, parentViewController) } func testSelectionInvokesHierarchyUpdaterWithCorrectView() { let expectation = expectationWithDescription("View hierarchy will be updated") let router = TabItemViewControllerRouter(tabComponents: [tabComponent1, tabComponent2], parentViewController: parentViewController, viewHierarchyUpdater: { view in XCTAssertEqual(view, self.tabComponent1.view) expectation.fulfill() }) router.selectTabItem(tabComponent1.tabItem) waitForExpectationsWithTimeout(2) { error in if let _ = error { XCTFail() } } } }