UIApplication.sharedApplication().делегат как AppDelegate вызывает EXC плохой доступ, используя его в модульном тесте 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 это Встроенный.RawPointer. Не знаю, что это такое, я не знаком с низкого уровня.
3 ответов
я думаю, вы добавили 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
от тестовых целевых членов.
с обновлением Swift 2.0 продолжайте использовать решение rintaro. Но вы можете упростить это:
@testable импорт MyApp
тогда вам не нужно отмечать свой класс AppDelegate как открытый.
убедитесь, что ваш AppDelegate имеет "UIApplicationDelegate
" в его декларации. То есть:
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate {
и если вы делаете это для iOS,вам может потребоваться импортировать UIKit в верхней части этого файла.