在Swift TDD中模拟NSBundle

4

在TDD过程中,是否有可能模拟应用程���的NSBundle以返回可预测的结果?

例如:

我想测试当文件未保存到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() 返回false的 pathForResource?

1个回答

5
目前,NSBundle.mainBundle()是一个硬编码的依赖项。我们希望能够指定任何bundle,可能以mainBundle为默认值。答案是依赖注入。让我们使用首选的构造函数注入形式,并利用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()的结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接