UIApplication.sharedApplication()。委托作为AppDelegate导致EXC_BAD_ACCESS在swift单元测试中使用它

时间:2014-11-15 14:08:15

标签: unit-testing pointers swift

我试图在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。不知道那是什么,我不熟悉低级细节。

3 个答案:

答案 0 :(得分:10)

我认为您已将AppDelegate.swift添加到测试目标成员。

当您这样做时,AppName.AppDelegateAppNameTests.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