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

tsm1rwdh  于 2023-05-23  发布在  iOS
关注(0)|答案(2)|浏览(153)

我正在测试一个依赖于UserDefaults示例的类。在下面的示例代码中找到了here,我创建并设置了示例,如下所示:

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

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

w8rqjzmb

w8rqjzmb1#

理想情况下,不传递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 {
    // ...
}
1qczuiv0

1qczuiv02#

这是一个测试目标,所以提交它不应该是一个问题。一旦犯了一次就不用再担心了。
如果你想确保你在运行之间留下一个干净的状态,那么在拆卸时将它归零可能是一个好主意。

override func tearDownWithError() throws {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        try super.tearDownWithError()
        mockDefaults()
    }

这里mockDefaults()调用传递一个nil的值,生成一个plist:

<plist version="1.0">
<dict/>
</plist>

它呼吁:

private extension FakeInrangeTests {
    func mockDefaults(value: Bool? = nil) -> UserDefaults {
        MockDefaults.makeInrange(#file, value)
    }
}

它调用:

struct MockDefaults {
    static func make(
        _ file: String,
        value: Any? = nil,
        key: String?
    ) -> UserDefaults {
        let userDefaults = UserDefaults(suiteName: file)!
        userDefaults.removePersistentDomain(forName: file)
        if let value = value, let key = key {
            userDefaults.setValue(value, forKey: key)
        }
        return userDefaults
    }
}

extension MockDefaults {
    static func makeInrange(
        _ file: String,
        _ value: Bool?
    ) -> UserDefaults {
        MockDefaults.make(
            file,
            value: value,
            key: UserDefaults.fakeInrangeKey
        )
    }
}

您可以将其添加到您的. gitignore。
*.swift.plist
您可以通过运行以下命令来确认未删除plist

var defaults: UserDefaults!

    override func setUpWithError() throws {
        continueAfterFailure = false
        try super.setUpWithError()
        defaults = UserDefaults(suiteName: #file)
        defaults.setValue(12, forKey: "myKey")
    }
    
    override func tearDownWithError() throws {
        try super.tearDownWithError()
        defaults.removePersistentDomain(forName: #file)
    }

相关问题