ios - 如何对静态属性进行单元测试?

标签 ios swift unit-testing static

我有一个 ConferenceNumberDirectory,它有一个 build 函数,该函数解析 JSON 文件以创建 ConferenceNumber 对象的静态数组。我想对这个函数进行单元测试。

我使用较小的 JSON 文件创建了一个单元测试来对此进行测试,但我的测试失败了,因为测试值只是简单地附加到实际值上。 ConferenceNumberDirectory.att 数组的实际值是 56 个条目,但是当我运行测试时,这些值仍然存在,并且我的测试值(13 个条目)附加到原始数组。如何测试我的静态属性而不用测试数据毒化它们?在之前的提交中,我的单元测试 ConferenceNumberDirectory.att 属性和实际的是单独的实体,我不知道这里发生了什么(自这次提交以来我没有更改我的测试类)。

class ConferenceNumberDirectory {

static var countryNumbers = [Any]()
static var att = [ConferenceNumber]()
static var arkadin = [ConferenceNumber]()
static var webex = [ConferenceNumber]()
static var zoom = [ConferenceNumber]()

   static func build(from rootJSONArray: [Any]?) {

do {
        guard let rootJSONArray = rootJSONArray else {
            throw SerializationError.missing("JSON Root")
        }

        for entry in rootJSONArray {
            guard let dictionary = entry as? [String: Any] else {
                throw SerializationError.missing("JSON Root")
            }
            guard let isoCode = dictionary["ISO Code"] as? String else {
                throw SerializationError.missing("isoCode")
            }
            guard let country = dictionary["Country"] as? String else {
                throw SerializationError.missing("country")
            }

            if let attTollNumbers = try self.extractNumbers(from: dictionary, forKey: "AT&T toll") {
                ConferenceNumberDirectory.att.append(contentsOf: attTollNumbers.map{ConferenceNumber(ISO: isoCode, country: country, number: $0, provider: ConferenceProvider.att, toll: true) })
            }
            print(ConferenceNumberDirectory.att.count)
            if let attTollFreeNumbers = try self.extractNumbers(from: dictionary, forKey: "AT&T toll-free") {
                ConferenceNumberDirectory.att.append(contentsOf: attTollFreeNumbers.map{ConferenceNumber(ISO: isoCode, country: country, number: $0, provider: ConferenceProvider.att, toll: false)})
            }
            if let arkadinTollNumbers = try self.extractNumbers(from: dictionary, forKey: "Arkadin toll") {
                ConferenceNumberDirectory.arkadin.append(contentsOf: arkadinTollNumbers.map{ConferenceNumber(ISO: isoCode, country: country, number: $0, provider: ConferenceProvider.arkadin, toll: true) })
            }
            if let arkadinTollFreeNumbers = try self.extractNumbers(from: dictionary, forKey: "Arkadin toll-free") {
                ConferenceNumberDirectory.arkadin.append(contentsOf: arkadinTollFreeNumbers.map{ConferenceNumber(ISO: isoCode, country: country, number: $0, provider: ConferenceProvider.arkadin, toll: false) })
            }
            if let webexTollNumbers = try self.extractNumbers(from: dictionary, forKey: "Webex toll") {
                ConferenceNumberDirectory.webex.append(contentsOf: webexTollNumbers.map{ConferenceNumber(ISO: isoCode, country: country, number: $0, provider: ConferenceProvider.webex, toll: true) })
            }
            if let webexTollFreeNumbers = try self.extractNumbers(from: dictionary, forKey: "Webex toll-free") {
                ConferenceNumberDirectory.webex.append(contentsOf: webexTollFreeNumbers.map{ConferenceNumber(ISO: isoCode, country: country, number: $0, provider: ConferenceProvider.webex, toll: false) })
            }
            if let zoomTollNumbers = try self.extractNumbers(from: dictionary, forKey: "Zoom toll") {
                ConferenceNumberDirectory.zoom.append(contentsOf: zoomTollNumbers.map{ConferenceNumber(ISO: isoCode, country: country, number: $0, provider: ConferenceProvider.zoom, toll: true) })
            }
        }
    }
    catch let error {
        print(error)
    }

}

最佳答案

由于您的属性是静态的,它们在代码的整个执行过程中都存在——不需要类的实际实例来将它们保留在内存中。这就是为什么要谨慎使用 static 属性的原因。您可以在 Swift 中阅读有关 static 属性的更多信息 in the docs, under "Type properties" .

关于你手头的问题:
您应该在测试类中利用 tearDown() 方法,并将这些属性恢复到它们的空状态。 tearDown()XCTestCase 类中的一个方法,它在每个测试用例之后运行 - 您可以覆盖它以为您的测试提供自定义清理。一个简单的例子:

override func tearDown() {
    ConferenceNumberDirectory.att = []()
    super.tearDown()
}

编辑:
要设置测试环境,您可以覆盖类似的方法:

override func setUp() {
    super.setUp()
    ConferenceNumberDirectory.att = []()
}

此方法在每个测试用例运行之前运行。我强烈建议通读 XCTest documentation.

关于ios - 如何对静态属性进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45001067/

相关文章:

ios - 如何在 Swift 中删除字符串的最后一个路径组件?

android - 如何为我的 Espresso Activity 测试提供自定义应用程序类?

ios - 当 iPad 应用程序进入后台时关闭弹出窗口

ios - 为什么我无法通过使用 "usedRectForTextContainer"获取 textContainer 的 rect

objective-c - 切换到横向 View 并使用标签栏 Controller

Swift 为 c 中定义的结构定义双指针

ios - 调整 FontSizeToFitWidth 时裁剪 UILabel

swift - 使用 round() 在 Swift 中舍入

c++ - 通过将文本文件发送到标准输入来自动测试 Visual Studio 中的 C++ 控制台应用程序?

javascript - 重新接线: How is it possible for this function to execute without returning the specified return value