单元测试从启动视图控制器错误地执行代码
Posted
技术标签:
【中文标题】单元测试从启动视图控制器错误地执行代码【英文标题】:Unit test is incorrectly executing code from the launch view controller 【发布时间】:2015-12-11 20:11:51 【问题描述】:我有一个简单的结构如下,它是 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 生成的单元测试统计数据。
数字“241”实际上应该只是“1”。其他 240 次,该行正在从未测试的启动视图控制器执行。
如何阻止视图控制器代码执行?
提前致谢。
【问题讨论】:
【参考方案1】:单元测试在您正在运行的应用的上下文中运行。
我认为最好的办法是编写应用程序委托的 didFinishLaunchingWithOptions
,以便在通过测试启动时不调出视图控制器(或调出更简单的)
此答案提供了一种检查您的应用是否在单元测试中运行的方法:
https://***.com/a/30306450/3937
要停止第一个故事板的自动加载,请将其作为启动故事板删除,并按照以下答案自行编写加载代码:
https://***.com/a/16702730/3937
【讨论】:
感谢您的回答!但是我正在使用情节提要,并且我的启动情节提要设置在我的 xcodeproj 文件中。如果您使用情节提要,我不知道有什么方法可以阻止 VC 在 AppDelegate 中加载。如果可以的话,请您分享一个代码sn-p吗? 谢谢!!在代码中启动情节提要的第二个代码 sn-p 不太有效,但只需要在它之前添加以下行: self.window = UIWindow(frame: UIScreen.mainScreen().bounds)【参考方案2】:您应该使用setUp 方法(在您的单元测试类中),该方法在viewDidLoad
之后调用。
重写此方法以自定义测试用例中所有测试的初始状态。
这样,您可以在测试方法执行之前重置您需要的任何内容。
例如,我需要重置通过视图控制器调用的单例。请注意,您可以通过tearDown 方法在各个方法之间进行重置:
在每个测试完成后调用一次。覆盖此方法以执行任何每次测试的清理。
【讨论】:
【参考方案3】:您的问题有一个解决方案。您可以按照以下链接中的说明缩短您的应用启动。
How To: Unit Test Without Running The Entire App
【讨论】:
以上是关于单元测试从启动视图控制器错误地执行代码的主要内容,如果未能解决你的问题,请参考以下文章