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

Won*_*ray 8 nsuserdefaults ios xctest swift userdefaults

我正在测试一个依赖于 UserDefaults 实例的类。按照此处找到的示例代码,我创建并设置实例,如下所示:

override func setUp() {
    super.setUp()
    defaults = UserDefaults(suiteName: #file)
    defaults.removePersistentDomain(forName: #file)
}
Run Code Online (Sandbox Code Playgroud)

运行测试后,将在与此测试类相同的目录中创建一个 plist 文件。如果我的测试文件被命名,TestFile.swift则 plist 的名称为TestFile.swift.plist. 我很确定这是在调用suiteName:上面的初始化程序时生成的。我的问题是:测试完成后如何删除该文件?我尝试在测试方法中调用removeSuite(named: #file)removeVolatileDomain(forName: #file)和 ,但没有成功。打电话似乎也没有帮助。removePersistentDomain(forName: #file)tearDownsynchronize()

Jam*_*e A 4

理想情况下,您不应传递 的实际实例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
    }

}
Run Code Online (Sandbox Code Playgroud)

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

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

class UnitTestDefaults: DefaultsStorage {
    // ...
}
Run Code Online (Sandbox Code Playgroud)