Создание объекта CoreData в тестах с помощью простого init - PullRequest
1 голос
/ 04 апреля 2019

У меня есть набор NSManagedObject подклассов, которые используются ClassToBeTested.

ClassToBeTested работает только с несколькими свойствами подклассов NSManagedObject и не требует отношений или всего стека CoreData.

Можно ли как-то использовать одни и те же объекты в тестах, просто создавая их обычным способом:

        let template = CoreDataClass()
        template.name = randomString(length: 40) // This fails!
        templates.append(template)

В настоящее время происходит сбой с ошибкой:

сбой: перехвачено «NSInvalidArgumentException», «- [CoreDataClass setTemplate_name:]: нераспознанный селектор отправлен на экземпляр 0x600000af4c40"

1 Ответ

1 голос
/ 04 апреля 2019

Хотя я получаю другую ошибку ( не вызвал назначенный инициализатор ), когда я пытаюсь это сделать, в любом случае, ответ на ваш вопрос: Нет, вы не можете сделать это.

Но с NSPersistentContainer в наше время легко использовать одноэлементный стек данных в памяти для такого тестирования.Включите вашу модель данных в свой тестовый пакет, затем поместите это в глобальную область теста:

var sharedTestContext: NSManagedObjectContext = {
    // Swift is smart enough to execute this only once.
    let container = NSPersistentContainer(name: "<YourDataModelName>")
    let description = NSPersistentStoreDescription()
    description.type = NSInMemoryStoreType
    container.persistentStoreDescriptions = [description]
    container.loadPersistentStores { (description, error) in
        if let error = error {
            fatalError("Failed to load store for test: \(error)")
        }
    }
    return container.newBackgroundContext()
}()

И определите специальный инициализатор управляемого объекта для тестирования, например:

/**
 Initializes a managed object for testing

 - important:  This assumes your managed object subclass name is the same
 as its entity name.
 */
public extension NSManagedObject {
    convenience init(testContext: NSManagedObjectContext?) {
        let context = testContext ?? sharedTestContext
        /*  The following contraption is necessary to avoid warning:
         "Multiple NSEntityDescriptions claim the NSManagedObject subclass"
         For explanation see:
         https://stackoverflow.com/questions/51851485/multiple-nsentitydescriptions-claim-nsmanagedobject-subclass */
        let name = String(describing: type(of: self))
        let entity = NSEntityDescription.entity(forEntityName: name, in: context)!
        self.init(entity: entity, insertInto: context)
    }
}

Теперь выможете создать свой тестовый объект таким образом:

let template = CoreDataClass(testContext: nil)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...