我试图为依赖项添加扩展名以进行测试。依赖项是一个标记为final的类,我想创建一个模仿接口的协议,这样我就可以在我的测试中将实际实现换成模拟对象。如果扩展程序包含在我的项目中,我正在构建测试时遇到中止陷阱6错误。没有扩展,项目构建没有错误,但我无法传递我的依赖作为协议,这阻止我在我的测试中交换模拟对象。因为该类被标记为final,所以我不能将该对象子类化以将其添加到其中。
我添加了3个对象以允许此行为:
RealmProtocol.swift:这是一个模仿Realm对象的公共接口的协议(我的外部依赖,但这不是Realm特有的)。
import RealmSwift
protocol RealmProtocol {
func add(_ object: Object, update: Bool)
func beginWrite()
func commitWrite(withoutNotifying tokens: [NotificationToken]) throws
func object<Element: Object, KeyType>(ofType type: Element.Type, forPrimaryKey key: KeyType) -> Element?
func objects<Element: Object>(_ type: Element.Type) -> Results<Element>
}
MockRealm.swift:这是我对Realm.swift的模拟对象。在生产中,将使用Realm对象,在我的测试中,它将与MockRealm交换,以便我可以验证在正确的时间调用正确的方法。
import Foundation
import RealmSwift
@testable import RealmObjectMocking
class MockRealm: RealmProtocol {
var addCalled = false
var beginWriteCalled = false
var commitWriteCalled = false
var objectCalled = false
var objectsCalled = false
var objectReturn: Any?
func add(_ object: Object, update: Bool) {
addCalled = true
}
func beginWrite() {
beginWriteCalled = true
}
func commitWrite(withoutNotifying tokens: [NotificationToken]) throws {
commitWriteCalled = true
}
func object<Element: Object, KeyType>(ofType type: Element.Type, forPrimaryKey key: KeyType) -> Element? {
objectCalled = true
let object = objectReturn as? Element
return object
}
func objects<Element: Object>(_ type: Element.Type) -> Results<Element> {
objectsCalled = true
let realm = try! Realm()
return realm.objects(type)
}
}
Realm.swift:这是Realm对象的扩展,使其符合我的协议。如果项目中没有此文件,则构建时不会出现错误。包含这个,我得到中止陷阱6.由于我的协议匹配Realm对象上的现有公共方法,因此实现是空的。
import RealmSwift
extension Realm: RealmProtocol {}
我不确定这是否是扩展一个标记为final的类的问题,或者我是否在这里得到某种循环依赖,或者可能是另一个问题。许多帖子建议关闭优化以克服此错误,但这没有帮助。此外,当项目中包含类扩展时打开MockRealm.swift文件会导致编辑器崩溃。因此,我还为此问题提交了雷达。
以下是显示问题的示例项目的链接。示例应用程序中的代码与上面的代码相同:https://github.com/skladek/RealmObjectMocking
这似乎是一个Xcode错误,而不是一个实现问题。 Apple开发人员告诉我,这已在Xcode10-Beta 1中修复。我已经测试并确认。由于我的产品将在Xcode 10和iOS 12发布后推出,我很满意离开。