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

时间:2017-07-09 21:13:11

标签: 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)
    }

}

1 个答案:

答案 0 :(得分:1)

由于您的属性为static,因此它们贯穿整个代码的执行过程 - 不需要您的类的实际实例来保留在内存中。这就是为什么static属性应该谨慎使用的原因。您可以在Swift in the docs, under "Type properties"中详细了解static属性。

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

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

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

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

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