ios - 在 Swift TDD 中模拟 NSBundle

标签 ios swift unit-testing mocking tdd

是否可以模拟应用程序 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?

最佳答案

就目前而言,NSBundle.mainBundle() 是一个硬编码的依赖项。我们想要的是指定任何 包的能力,也许默认使用 mainBundle。答案是Dependency Injection .让我们使用构造函数注入(inject)的首选形式,并利用 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 不存在的情况。

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

关于ios - 在 Swift TDD 中模拟 NSBundle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34898283/

相关文章:

json - 需要帮助在 SWIFT 中解析 wikipedia json api

unit-testing - "framework:requirejs"没有提供者! (解决 : framework:requirejs)

java - 当通过公共(public) API 测试很难看时,如何在 Java 中测试私有(private)方法?

c# - Unitests 和 VS2012 Update 2 CTP 4 的问题

xcode - 我的 Interface Builder 库中的核心数据实体在哪里?

ios - 我如何从 iTunes 商店 xcode 下载特定轨道

ios - 未使用对象中的异常

ios - 本地化 Helpshift iOS Swift

swift - 使用未解析的标识符

ios - Storyboard手势识别器