这是我的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")
}
}
ListBusNumbersConfigurator.sharedInstance.configure(viewController: self)
中调用awakeFromNib
。这样,如果我在单元测试中调用viewDidLoad就不会调用它,从而允许使用Spy类进行测试方法调用。在代码中创建UI时,如何实现相同的效果?可以找到项目Clean Swift。
非常感谢任何帮助。