单元测试错误地从启动视图控制器执行代码

时间:2015-12-11 20:11:52

标签: ios swift unit-testing

我有一个简单的结构,如下所示,它是iOS应用程序的一部分:

struct Country: JSONObject {
    let name: String!
    let code: String!

    static let nameKey = "name"
    static let codeKey = "dial_code"

    init?(_ json: [String: AnyObject]) throws {
        guard let name = json[Country.nameKey] as? String else {
           throw JSONError.InvalidTypeForKey(key: Country.nameKey)
        }

        guard let code = json[Country.codeKey] as? String else {
            throw JSONError.InvalidTypeForKey(key: Country.codeKey)
        }

        self.name = name
        self.code = code
    }
}

我写了一个单元测试来测试这个类的初始化:

func testCorrectInitialisationOfCountry() {
    let countryDict = [Country.nameKey: "England", Country.codeKey: "+44"]

    do {
        let country = try Country(countryDict)!
        XCTAssert(countryDict[Country.nameKey] == country.name, "The country name does not match")
        XCTAssert(countryDict[Country.codeKey] == country.code, "The country code does not match")
    }
    catch _ {
        print("Initialisation of country failed with an exception")
    }
}

我遇到的问题是这个结构在我的应用程序的第一个视图控制器的viewDidLoad()方法中初始化了几次。

出于某种原因,当我运行测试并因此生成错误的代码覆盖时,正在调用viewDidLoad()方法。下图显示了Xcode生成的单元测试统计数据。

enter image description here

数字“241”实际上应该只是“1”。另外240次,该行正在从未启动的启动视图控制器执行。

如何停止执行视图控制器代码?

提前致谢。

3 个答案:

答案 0 :(得分:2)

单元测试在正在运行的应用程序的上下文中运行。

我认为你最好的选择是编写你的应用代表的didFinishLaunchingWithOptions,如果通过测试启动(或调出一个更简单的控制器),则不会启动视图控制器。

此答案提供了一种检查您的应用是否在单元测试中运行的方法:

https://stackoverflow.com/a/30306450/3937

要停止自动加载第一个故事板,请将其作为启动故事板删除,并按照以下答案自行编码:

https://stackoverflow.com/a/16702730/3937

答案 1 :(得分:0)

您应该使用setUp方法(在单元测试类中),该方法被调用 AFTER viewDidLoad

  

重写此方法以自定义测试用例中所有测试的初始状态。

这样,您可以在测试方法执行之前重置所需的任何内容。

例如,我需要重置通过视图控制器调用的单例。请注意,您可以通过tearDown方法在每种方法之间重置:

  每次测试完成后,

调用一次。重写此方法以执行任何每次测试清理。

答案 2 :(得分:0)

有一个解决您的问题的方法。您可以按照以下链接中的说明短路应用启动。

How To: Unit Test Without Running The Entire App