我试图在swift中使用单元测试来测试一些真正的应用程序行为。
当我尝试从我的测试函数中将de UIApplicationDelegate
强制转换为AppDelegate
时,我得到了EXC_BAD_ACCESS异常。测试代码下方:
func testGetAppDelegate(){
let someDelegate = UIApplication.sharedApplication().delegate
let appDelegate = someDelegate as AppDelegate //EXC_BAD_ACCESS here
XCTAssertNotNil(appDelegate, "failed to get cast pointer")
}
AppDelegate类设置为public,因此访问级别不存在问题。
在同一测试目标中使用objective-c可行。简单说明下面:
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
debuger说someDelegate是一个Builtin.RawPointer。不知道那是什么,我不熟悉低级细节。
答案 0 :(得分:10)
我认为您已将AppDelegate.swift
添加到测试目标成员。
当您这样做时,AppName.AppDelegate
和AppNameTests.AppDelegate
会成为不同的类。然后,UIApplication.sharedApplication().delegate
返回AppName.AppDelegate
个实例,但您尝试将其转换为AppNameTests.AppDelegate
类型。这会导致EXC_BAD_ACCESS
。
而不是那样,你必须从你的应用程序模块中导入它。
import UIKit
import XCTest
import AppName // <- HERE
class AppNameTests: XCTestCase {
// tests, tests...
}
并且,AppDelegate
类及其方法和属性必须声明为public
才能从测试模块中看到。
import UIKit
@UIApplicationMain
public class AppDelegate: UIResponder, UIApplicationDelegate {
public var window: UIWindow?
public func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
return true
}
// ...
同样,请务必从测试目标成员中删除AppDelegate.swift
。
答案 1 :(得分:2)
使用Swift 2.0更新,继续使用rintaro的解决方案。但你可以通过以下方式简化它:
@testable导入MyApp
然后您不需要将AppDelegate类标记为公开。
答案 2 :(得分:0)
确保您的AppDelegate在其声明中包含“UIApplicationDelegate
”。那就是:
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate {
如果您正在为iOS执行此操作,you might need to import UIKit at the top of this file。