- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
大家好,我正在尝试测试我项目的其中一个 ViewController。此类依赖于另一个辅助类,如下所示:
private let dispatcher: Dispatcher = Dispatcher.sharedInstance
private var loginSync = LoginSync.sharedInstance
private var metadataSync = MetadataSync.sharedInstance
这些辅助类在 UIViewController 生命周期中使用,如 viewDidLoad 或 viewWillAppear。在我的测试中,我使用 UIStoryboard 类实例化 ViewController 类,如下所示:
func testSearchBarAddedIntoNavigationViewForiOS11OrMore() {
// Given a YourFlow ViewController embedded in a navigation controller
let mockLoginSync = MockLoginSync()
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// Here is too early and view controller is not instantiated yet and I can't assign the mock.
let vc = storyboard.instantiateViewController(withIdentifier: "YourFlow")
// Here is too late and viewDidLoad has already been called so assigning the mock at this point is pointless.
let navigationController = UINavigationController(rootViewController: vc)
// Assertion code
}
所以我的问题是我需要能够模拟 LoginSync 类。在正常情况下,我会通过将这些助手作为类构造函数中的参数传递来使用常规依赖注入(inject)。在那种情况下,我不能那样做,因为我没有管理 View Controller 生命周期。所以我一实例化它,助手就已经被使用了。
我的问题是:“有没有办法为我们无法控制其生命周期的 View Controller 进行依赖注入(inject),或者至少有解决方法?
谢谢。
编辑:所以调用 viewDidLoad 是因为我在 didSet 覆盖方法中使用了 IBOutlets,而不是因为调用了 instantiateViewController。所以我可以移开该代码并在正确实例化 View Controller 后进行注入(inject)。
最佳答案
您可以像这样包装 UIVIewControllerCreation
:
class func createWith(injection: YourInjection) -> YourViewController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "YourVCId") as? YourViewController
vc.injected = injection
return vc
}
像这样使用它:
let vc = YourViewController.createWith(<your injection>)
这是一个例子:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let vc = RedViewController.createWith(injection: "some")
navigationController?.pushViewController(vc, animated: true)
}
}
class RedViewController: UIViewController {
var injected: String = "" {
didSet {
print(#function)
}
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
print(#function)
}
class func createWith(injection: String) -> RedViewController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "Red") as! RedViewController
vc.injected = injection
return vc
}
}
Storyboard设置:
代码运行结果打印:
injected
viewDidLoad()
如您所见,注入(inject)发生在 viewDidLoad() 之前
关于ios - 如何在 Storyboard管理的 UIViewControllers 中依赖注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52888893/
我是一名优秀的程序员,十分优秀!