【问题标题】:XCTests and PHPhotoLibraryXCTests 和 PHPhotoLibrary
【发布时间】:2017-12-07 17:52:22
【问题描述】:

我在应用程序中有将图片保存在照片库中的功能。我想知道如何测试这段代码:

func saveInPhotoGallery() {
    guard self.cameraOutput != nil else { return }
    if self.cameraOutput is UIImage {
        PHPhotoLibrary.shared().performChanges({
            PHAssetChangeRequest.creationRequestForAsset(from: (self.cameraOutput as? UIImage)!)
        }, completionHandler: { (saved, error) in
            guard error == nil else {
               self.unsucessfullSavingOperation(error)
               return
            }
        })
    }
}

现在假设我想在我的案例场景中测试self.cameraOutput 是和UIImage 和某事出错并且completionHandler 中存在错误所以我最终使用了self.unsucessfullSavingOperation(error) 方法。这当然有单独的测试,但我想介绍的是:

确保每当在相机胶卷中插入图像出现问题时,我都会调用此方法

当我尝试在测试目标中调用 saveInPhotoGallery() 时,它会发出警报,表明这需要访问您的照片库(哦!)。但是有一种方法可以在 Unit Tests 中跳过此警报,或者检查它是否弹出并按 allow? (就像我说的,对于这个测试,假设我有这个权限)

或者有办法模拟这种行为?

【问题讨论】:

    标签: ios swift xctest xctestcase


    【解决方案1】:

    是的,我会模拟 PHPhotoLibrary。您需要替换的主要内容是使用PHPhotoLibrary.shared(),它创建了对具体实例的依赖关系。相反,我们可以依赖一个抽象,即协议。

    然后生产代码可以提供PHPhotoLibrary.shared() 作为要使用的实例。测试代码可以提供一个模拟对象。

    如果您需要更多关于打破依赖或制作模拟对象或两者的详细说明,请告诉我。

    【讨论】:

    • 谢谢,很清楚,但想知道这样做是否真的值得,因为模拟对象可以返回错误,成功,假设我将测试self.unsucessfullSavingOperation(error) 和成功操作相同。既然我测试了函数以分别处理所有可能的输出,那么仍然有嘲笑的意义吗?
    • 那么您已经对unsucessfullSavingOperation 进行了单元测试?在这种情况下,模拟可以让您将这些测试处理得更上一层楼。这将使saveInPhotoGallery 处于测试状态,这将使您可以安全地重构它。它还会使unsucessfullSavingOperation 成为隐藏的实现细节。
    • 在这种情况下,您还会模拟 PHAssetChangeRequest 吗?我正在尝试测试类似的场景,但也尝试使用 var assetPlaceholder: PHObjectPlaceholder = assetChangeRequest.placeholderForCreatedAsset let localID = assetPlaceholder.localIdentifier 测试资产 localIdentifier
    • @EdwardFord 看起来 PHAssetChangeRequest 并不容易从中获取信息。也许看看测试间谍是否会起作用。那是您对原始类进行子类化的地方,但添加了捕获难以提取的信息的方法。完整的模拟也可能有效。我不知道哪个会更好——你必须试试看。
    猜你喜欢
    • 2016-08-15
    • 2015-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    • 2014-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多