没有Storyboard的viewDidLoad测试

时间:2017-02-17 00:46:00

标签: ios swift unit-testing uikit

我正在尝试应用http://www.ebay.co.uk/itm/Luxury-Magnetic-Flip-Cover-Stand-Wallet-Leather-Case-For-Apple-iPhone-Models-/172423423931?var=&hash=item28253ca7bb:m:mUL-SeQQB128hGq-rt62LJw中解释的清洁架构。

这是我的didFinishLaunchingWithOptions实现创建没有Storyboard或XIB的UI:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
{
  // Override point for customization after application launch.
  let listBusNumbersViewController = ListBusNumbersViewController(style: .plain)
  let navigationController = UINavigationController(rootViewController: listBusNumbersViewController)
  window!.rootViewController = navigationController
  window!.makeKeyAndVisible()
  return true
}

这是ListBusNumbersViewController中的viewDidLoad实现:

override func viewDidLoad()
{
  super.viewDidLoad()
  ListBusNumbersConfigurator.sharedInstance.configure(viewController: self)
  self.title = "Bus Numbers"
  searchController.delegate = self
  searchController.searchResultsUpdater = self
  searchController.searchBar.delegate = self
  searchController.searchBar.sizeToFit()
  searchController.searchBar.layer.cornerRadius = 0.0
  searchController.searchBar.searchBarStyle = .minimal
  self.tableView.register(ListBusNumbersTableViewCell.self, forCellReuseIdentifier: "ListBusNumbersTableViewCell")
  self.tableView.translatesAutoresizingMaskIntoConstraints = false
  self.tableView.tableHeaderView = searchController.searchBar
  self.tableView.backgroundColor = .white
  fetchBusNumbersOnLoad()
}

fetchBusNumbers的实施:

func fetchBusNumbersOnLoad()
{
  let request = ListBusNumbers.FetchBusNumbers.Request()
  output.fetchBusNumbers(request: request)
}

在我的单元测试中,我需要测试是否正在调用output.fetchBusNumbers。这是单元测试:

class ListBusNumbersViewControllerTests: XCTestCase
{
  // MARK: - Subject under test

  var sut: ListBusNumbersViewController!
  var window: UIWindow!

  // MARK: - Test lifecycle

  override func setUp()
  {
    super.setUp()
    window = UIWindow()
    sut = ListBusNumbersViewController(style: .plain)
    UIApplication.shared.keyWindow!.rootViewController = sut
    //setupListBusNumbersViewController()
  }

  override func tearDown()
  {
    //window = nil
    super.tearDown()
  }

  class ListBusNumbersViewControllerOutputSpy: ListBusNumbersViewControllerOutput
  {
    // MARK: - Method call expectations
    var fetchBusNumbersCalled = false

    // MARK: Spied methods
    func fetchBusNumbers(request: ListBusNumbers.FetchBusNumbers.Request)
    {
      fetchBusNumbersCalled = true
    }
  }

  // MARK: - Test setup

  //func setupListBusNumbersViewController()
  //{
  //  let bundle = Bundle.main
  //  let storyboard = UIStoryboard(name: "Main", bundle: bundle)
  //  sut = storyboard.instantiateViewController(withIdentifier: "ListBusNumbersViewController") as! ListBusNumbersViewController
  //}

  func loadView()
  {
    window.rootViewController = sut
    RunLoop.current.run(until: Date())
  }

  // MARK: - Test doubles

  // MARK: - Tests

  func testShouldFetchBusNumbersWhenViewIsLoaded()
  {
    // Given
    let listBusNumbersViewControllerOutputSpy = ListBusNumbersViewControllerOutputSpy()
    sut.output = listBusNumbersViewControllerOutputSpy

    // When
    loadView()
    // Then
    XCTAssertNotNil(sut.view, "ListBusNumbersViewController should have been loaded")
    XCTAssert(listBusNumbersViewControllerOutputSpy.fetchBusNumbersCalled, "Should fetch bus numbers when the view is loaded")
  }
}
  1. 如果我使用Storyboard,我可以在ListBusNumbersConfigurator.sharedInstance.configure(viewController: self)中调用awakeFromNib。这样,如果我在单元测试中调用viewDidLoad就不会调用它,从而允许使用Spy类进行测试方法调用。在代码中创建UI时,如何实现相同的效果?
  2. 如何在单元测试中调用viewDidLoad?
  3. 可以找到项目Clean Swift

    非常感谢任何帮助。

0 个答案:

没有答案