ios - 向下转换/子类 UIViewController 用于单元测试中的模拟
问题描述
我有一个单元测试,我想创建一个 的子类版本UIViewController
,例如Test1ViewController
. 具体来说,我想重写present
这个类的方法。
我有一个视图控制器扩展,它根据其类名实例化视图控制器。
public class func instanceFromStoryboard<T>(storyboard: Storyboard) -> T {
return UIStoryboard(name: storyboard.rawValue, bundle: nil).instantiateViewController(withIdentifier: String(describing: T.self)) as! T
}
还有一个故事板课程。
public enum Storyboard: String {
case main = "Main"
}
在我的单元测试中,我从Test1ViewController
.
class Test2ViewController: Test1ViewController {
var presented: Bool = false
override func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
presented = true
}
}
如何使用我的扩展方法从情节提要中检索视图控制器,然后向下转换/子类化为Test2ViewController
?
解决方案
如果您的最终目标是验证UIViewController
被测对象是否呈现了某些东西,您是否考虑过检查该presentedViewController
属性?
// Create an asynchronous expectation to verify the view controller has presented
// something.
_ = expectation(
for: NSPredicate(
block: { input, _ -> Bool in
guard let viewController = input as? UIViewController else { return false }
// If you care about the type of the presented view controller you could
// use `is` here to verify it
return viewController.presentedViewController != nil
}
),
evaluatedWith: viewControllerUnderTest,
handler: .none
)
viewControllerUnderTest.doSomething()
waitForExpectations(timeout: 1, handler: nil)
另一种方法,它需要更多的工作,但随着时间的推移,通过使您的视图控制器更容易在导航流中移动而得到回报,是对所有演示文稿使用委托。
在测试中,您不会检查是否已呈现某些内容,但仅当使用Spy 测试 double调用了呈现某些内容的导航委托方法时。如果您对这种方法感到好奇,很高兴提供更多详细信息。
推荐阅读
- python - 展平嵌套列表
- c# - 如何设置 Microsoft 标识以尊重默认文件名
- asp.net-core - .NET Core 2.1 Swashbuckle - 按区域分组控制器
- c# - 强制认证中间件只接受加密令牌
- python - 对列表进行就地更改的函数
- python - 当一些数据有微秒而一些没有时使用Strptime
- javascript - 在浏览器中滑动但在 Android 中不起作用 - Cordova
- python - 构建 Docker 映像时 pip 安装期间出现 CondaValueError
- javascript - Javascript:我在一个页面上有多个触发按钮,但它们都触发了最后一个事件
- karate - 空手道 - 在标题之间切换