2015-05-15 3 views
9

Мне нужно провести тестирование (XCTest) некоторых из моих методов, которые включают ссылку на модели CoreData.swift - Тестирование модели CoreData (+ MagicalRecord) триггеров модели EXC_BAD_ACCESS

Следующая строка выполнить правильно:

var airport: AnyObject! = Airport.MR_createEntity() 

(lldb) po airport <Airport: 0x7fcf54216940> (entity: Airport; id: 0x7fcf54216a20 <x-coredata:///Airport/t1D3D08DA-70F9-4DA0-9487-BD6047EE93692> ; data: { 
    open = nil; 
    shortName = nil; 
    visible = nil; }) 

а следующая строка запускает EXC_BAD_ACCESS:

var airport2: Airport = Airport.MR_createEntity() as! Airport 

(lldb) po airport2 
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x0). 
The process has been returned to the state before expression evaluation. 

Нет знак этой ошибки с моей главной целью. Конфигурация: объекты модели в обеих целях, класс с префиксом @objc(MyModel), без пространства имен в классах в моих xcdatamodel

Любая идея, что здесь происходит?

+0

Вы отметили свои методы и свойства как общедоступные в своем классе Airport?Быстрое управление доступом может быть проблемой – railwayparade

+0

Просто попытался, тот же результат :( – Yaman

+0

Я закончил создание объектов вручную без сокращения MR для вставки ... –

ответ

3

Правильно, поэтому я, наконец, добрался до сути и не очень красив. Фактически для этой проблемы есть radar, поскольку она кажется ошибкой с компилятором Swift, который не распознает листинг ManagedObject в тестовых целях. Так добавить свой голос к шуму

трогания с объектом определяется следующим образом:

@objc(Member) 
class Member: NSManagedObject {  
    @NSManaged var name: String 
} 

Я написал простой тестовый класс, в котором я создаю MO 3 разных способов:

Первый два не удалось:

let context = NSManagedObjectContext.MR_defaultContext() 

func testMagicalRecordCreation() { 
    let m = Member.MR_createInContext(context) as? Member 
    XCTAssertNotNil(m, "Failed to create object")//fails 
} 

func testEntityDescriptionClassCreation() { 
    let m2 = NSEntityDescription.insertNewObjectForEntityForName("Member", inManagedObjectContext: context) as? Member 
    XCTAssertNotNil(m2, "Failed to create object")//fails 
} 

, а затем успех

func testManualMOCreation() { 
    let ent = NSEntityDescription.entityForName("Member", inManagedObjectContext: context)! 
    let m3 = Member(entity: ent, insertIntoManagedObjectContext: context) 
    XCTAssertNotNil(m3, "Failed to create object") 
} 

Это означает, что прямо сейчас у вас есть два варианта. Напишите свои тесты в Objective-C; или создать метод утилиты для вставки тестовых объектов в контекст с использованием средств, показанных выше.

Theres хороший пост об этом поведении here

Я закончил с использованием расширения NSManagedObjectContext для использования в явном виде в Swift Тесты:

extension NSManagedObjectContext { 
    func insertTestEntity<T: NSManagedObject>(entity: T.Type) -> T { 
     let entityDescription = NSEntityDescription.entityForName(NSStringFromClass(T.self), inManagedObjectContext: self)! 
     return T(entity: entityDescription, insertIntoManagedObjectContext: self) 
    } 
} 

И это может быть использовано, как это:

func testConvenienceCreation() { 
    let m4 = context.insertTestEntity(Member) 
    XCTAssertNotNil(m4, "Failed to create object") 
} 

Подробнее о таком подходе here

0

Есть два способа, чтобы сделать ваши Swift классы приложений, доступных для тестовой цели:

  1. Сделать классы приложения общественности - это включает в себя все переменные, постоянные и функция, которую вы хотите проверить

  2. Добавьте приложение Swift в тестовый объект. Это довольно просто сделать.

+0

, это не то, о чем спрашивает OP ... –

Смежные вопросы