运行 单元测试时删除 UserDefaults 生成的 plist 文件

Removing UserDefaults-generated plist file when running unit tests

我正在测试一个依赖于 UserDefaults 实例的 class。在找到 here 之后的示例代码中,我创建并设置了这样的实例:

override func setUp() {
    super.setUp()
    defaults = UserDefaults(suiteName: #file)
    defaults.removePersistentDomain(forName: #file)
}

在 运行 测试之后,将在与此测试 class 相同的目录中创建一个 plist 文件。如果我的测试文件名为 TestFile.swift,则 plist 的名称为 TestFile.swift.plist。我很确定这是在调用上面的 suiteName: 初始化程序时生成的。我的问题是:测试完成后如何删除此文件?我试过在测试的 tearDown 方法中调用 removeSuite(named: #file)removeVolatileDomain(forName: #file)removePersistentDomain(forName: #file),但没有成功。致电 synchronize() 似乎也无济于事。

理想情况下,不是传递 UserDefaults 的实际实例,而是传递不需要该清理的不同类型的对象。一个简单的例子是这样的:

class UnitTestDefaults: UserDefaults {

    private var values = [String: Any]()

    // override only the functions you need, e.g.

    override func object(forKey defaultName: String) -> Any? {
        values[defaultName]
    }

    override func set(_ value: Any?, forKey defaultName: String) {
        values[defaultName] = value
    }

}

或者,您可以定义一个新协议并让您正在测试的对象依赖于该协议的实例而不是 UserDefaults。这将被认为是单元测试更合适的做法,并且如果简单地创建 UserDefaults 的实例也可以解决您的问题,即使是未定义自定义套件的子类,仍然有不需要的副作用。

protocol DefaultsStorage {
    func object(forKey defaultName: String) -> Any?
    func set(_ value: Any?, forKey defaultName: String)
}

class UnitTestDefaults: DefaultsStorage {
    // ...
}