我想将数据管理器注入视图控制器并对其进行测试。
ViewController:
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var alert: AlertViewController?
var coreDataManager: CoreDataManagerProtocol?
init(coreDataManager: CoreDataManagerProtocol) {
self.coreDataManager = coreDataManager
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.coreDataManager = CoreDataManager()
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
@IBAction func addItem(_ sender: Any) {
alert = UIStoryboard(name: Constants.alertStoryBoard, bundle: nil).instantiateViewController(withIdentifier: Constants.alerts.mainAlert) as? AlertViewController
alert?.title = "Enter your task"
alert?.presentToWindow()
alert?.delegate = self
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return coreDataManager?.getTasks().count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let data = coreDataManager?.getTasks()[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = data?.value(forKey: Constants.entityNameAttribute) as? String
return cell
}
}
我想通过在模拟中注入视图控制器来对此进行测试:
class CoreDataManagerMock: CoreDataManagerProtocol {
var storeCordinator: NSPersistentStoreCoordinator!
var managedObjectContext: NSManagedObjectContext!
var managedObjectModel: NSManagedObjectModel!
var store: NSPersistentStore!
func getTasks() -> [NSManagedObject] {
managedObjectModel = NSManagedObjectModel.mergedModel(from: nil)
storeCordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)
do {
store = try storeCordinator.addPersistentStore(
ofType: NSInMemoryStoreType, configurationName: nil, at: nil, options: nil)
} catch {
// catch failure here
}
managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = storeCordinator
var localTasks = [NSManagedObject]()
let entityOne = NSEntityDescription.insertNewObject(forEntityName: Constants.entityName, into: managedObjectContext)
entityOne.setValue(false, forKey: Constants.entityCompletedattribute)
entityOne.setValue("Enter your task", forKey: Constants.entityNameAttribute)
localTasks.append(entityOne)
return localTasks
}
func save(task: String) {
//
}
}
但我正在努力对此进行测试。
我无法请求一个单元,因为我没有从情节提要中实例化(而且我不能,因为我需要注入模拟核心管理器。
在每次尝试运行tableView的测试中,解析为nil
这是我的尝试,认为我可以直接测试cellForRowAt函数:
func testtv() {
let CDM = CoreDataManagerMock()
let viewController = ViewController(coreDataManager: CDM)
viewController.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
viewController.tableView(UITableViewMock(), cellForRowAt: IndexPath(row: 0, section: 0))
let actualCell = viewController.tableView?.cellForRow(at: IndexPath(row: 0, section: 0) )
let test = viewController.tableView(UITableViewMock(), cellForRowAt: IndexPath(row: 0, section: 0))
XCTAssertEqual(actualCell?.textLabel?.text, actualCell?.textLabel?.text)
}
但是由于tableView为nil为nil,所以我无法注册该单元格。我如何测试cellForRow(at:当我如上所述注入依赖项时?
答案 0 :(得分:0)
通过这样做,我如何对实例化UIStoryboard
的{{1}}进行测试。
UIViewController
所以在您的情况下,因为这是代码的样子:
// STEP 1
// instantiate the storyboard
let storyboard = UIStoryboard(name: "SomeStoryboard", bundle: nil)
// STEP 2
// instantiate the UIViewController using the storyboard
let sampleViewController = storyboard.instantiateViewController(withIdentifier: "SampleViewController") as! SampleViewController
// STEP 3
// set the properties you need to set
sampleViewController.xxxxx = "foo"
sampleViewController.yyyyy = "bar"
// STEP 4
// call the view so the ui objects would be instantiated
// not doing this would cause a crash
// this also calls `viewDidLoad()`
_ = sampleViewController.view
ViewController
这是因为调用func testtv() {
let storyboard = UIStoryboard(name: "INSERT STORYBOARD NAME HERE", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
viewController.coreDataManager = CoreDataManagerMock()
_ = viewController.view
// I'm not sure about the code below this comment
// but the above code should work
viewController.tableView(UITableViewMock(), cellForRowAt: IndexPath(row: 0, section: 0))
let actualCell = viewController.tableView?.cellForRow(at: IndexPath(row: 0, section: 0) )
let test = viewController.tableView(UITableViewMock(), cellForRowAt: IndexPath(row: 0, section: 0))
XCTAssertEqual(actualCell?.textLabel?.text, actualCell?.textLabel?.text)
}
使用instantiateViewController(withIdentifier: _)
您可以在下面删除此代码段,因为您不需要它,而且由于您要实例化的init?(coder aDecoder: NSCoder)
来自情节提要,因此该代码段也无效。
UIViewController
您可以做的是创建一个静态方法,用您需要的参数实例化init(coreDataManager: CoreDataManagerProtocol) {
self.coreDataManager = coreDataManager
super.init(nibName: nil, bundle: nil)
}
。示例:
UIViewController