ViewController计算其实例:
class ViewController: UIViewController {
static var instances: Int = 0
override func viewDidLoad() {
ViewController.instances = ViewController.instances + 1
super.viewDidLoad()
}
deinit {
ViewController.instances = ViewController.instances - 1
}
}
在默认的iOS Single View App中尝试它,它将是应用程序UIWindow的根视图控制器。
单元测试尝试通过在同一UIWindow上放置一个虚拟视图控制器来检查结果:
func testExample() {
guard let w = UIApplication.shared.delegate?.window else { return }
w?.rootViewController = UIViewController()
XCTAssert(ViewController.instances == 0)
}
但测试失败,ViewController尚未发布。
我猜测主机应用程序的autoreleasepool只在单元测试运行后才会耗尽。有没有办法在测试ViewController.instances之前将其耗尽?还有其他方法来编写这样的测试吗?
我认为在你的片段中,window
保留了ViewController
。
我解决这个问题的方法是覆盖tearDown()
并确保window.rootViewController
(以及我在setUp()中创建的任何其他内容都设置为nil:
var window: UIWindow!
override func tearDown() {
window.rootViewController = nil
window = nil
super.tearDown()
}
编辑。要验证是否已调用viewcontroller deinit方法,您可以执行以下操作:
func testExample() {
autoreleasepool {
self.window?.rootViewController = UIViewController()
}
expect(Myvc.retaincount).toEventually(equal(0))
}
这是使用Nimble测试框架等待值为0.你应该能够使用异步测试在普通的XCTest中编写它。