【问题标题】:Mocking NSBundle in Swift TDD在 Swift TDD 中模拟 NSBundle
【发布时间】:2016-01-20 11:04:08
【问题描述】:

是否可以模拟应用程序 NSBundle 以在 TDD 期间返回可预测的结果?

例如:

我想测试我的应用程序在文件未保存到 NSBundle 时的处理能力:

//Method to test
func getProfileImage() -> UIImage {
    if let profileImagePath = getProfilePhotoPath() {
        UIImage(contentsOfFile: profileImagePath)
    }
    return UIImage(named: "defaultProfileImage")
}

private func getProfilePhotoPath() -> String? {
    return NSBundle.mainBundle().pathForResource("profileImage", ofType: "png")
}

是否可以模拟 NSBundle.mainBundle() 为 pathForResource 返回 false?

【问题讨论】:

    标签: ios swift unit-testing mocking tdd


    【解决方案1】:

    就目前而言,NSBundle.mainBundle() 是硬编码的依赖项。我们想要的是能够指定 any 捆绑包,也许将 mainBundle 作为默认值。答案是Dependency Injection。让我们使用构造函数注入的首选形式,并利用 Swift 的默认参数:

    class ProfileImageGetter {
        private var bundle: NSBundle
    
        init(bundle: NSBundle = NSBundle.mainBundle()) {
            self.bundle = bundle
        }
    
        func getProfileImage() -> UIImage {
            if let profileImagePath = getProfilePhotoPath() {
                return UIImage(contentsOfFile: profileImagePath)!
            }
            return UIImage(named: "defaultProfileImage")!
        }
    
        private func getProfilePhotoPath() -> String? {
            return bundle.pathForResource("profileImage", ofType: "png")
        }
    }
    

    现在测试可以实例化 ProfileImageGetter 并指定它喜欢的任何包。这可能是测试包,也可能是假的。

    指定测试包将允许您遇到 profileImage.png 不存在的情况。

    指定一个假的会让你存根调用pathForResource()的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-24
      • 2014-08-02
      • 2015-01-23
      • 2016-10-22
      • 1970-01-01
      • 2011-10-09
      相关资源
      最近更新 更多