Last active
October 30, 2017 21:07
-
-
Save bstien/cf378c280479520b918061573f8b36c8 to your computer and use it in GitHub Desktop.
Testing ViewModel with Core Data
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import RxCoreData | |
import CoreData | |
// The entity's name in .xcdatamodeld is 'Item'. It has empty fields for both Class and Module. Codegen is 'Manual/None'. | |
struct Item { | |
var date: Date | |
} | |
extension Item: Persistable { | |
public typealias T = NSManagedObject | |
public static var entityName: String { return "Item" } | |
public static var primaryAttributeName: String { return "date" } | |
public var identity: String { return date.debugDescription } | |
public init(entity: T) { | |
date = entity.value(forKey: "date") as! Date | |
} | |
public func update(_ entity: NSManagedObject) { | |
entity.setValue(date, forKey: "date") | |
do { | |
try entity.managedObjectContext?.save() | |
} catch { | |
print(error) | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import CoreData | |
import RxSwift | |
import RxCocoa | |
import RxCoreData | |
// The view-model I'm trying to test. | |
class ViewModel { | |
let items: Driver<[Item]> | |
let addItem = PublishSubject<Void>() | |
let disposeBag = DisposeBag() | |
let moc: NSManagedObjectContext | |
init(managedObjectContext: NSManagedObjectContext) { | |
moc = managedObjectContext | |
items = moc.rx.entities(Item.self, sortDescriptors: [NSSortDescriptor(key: "date", ascending: false)]).asDriver(onErrorJustReturn: []) | |
addItem.bindNext { | |
let item = Item(date: Date()) | |
do { try self.moc.rx.update(item) } catch { print(error) } | |
}.disposed(by: disposeBag) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import CoreData | |
import RxCoreData | |
import RxSwift | |
import RxTest | |
import Quick | |
import Nimble | |
@testable import CoreDataAppTarget | |
// Unit testing the view-model. | |
class ViewModelQuickTest: QuickSpec { | |
override func spec() { | |
var scheduler: TestScheduler! | |
var disposeBag: DisposeBag! | |
var moc: NSManagedObjectContext! | |
var subject: ViewModel! | |
beforeEach { | |
scheduler = TestScheduler(initialClock: 0) | |
disposeBag = DisposeBag() | |
moc = self.inMemoryStack() | |
subject = ViewModel(managedObjectContext: moc) | |
} | |
it("Adds an Item on events") { | |
let result = scheduler.createObserver([Item].self) | |
let addItem = scheduler.createColdObservable([next(100, ()), next(200, ())]) | |
subject.items.drive(result).disposed(by: disposeBag) | |
addItem.bindTo(subject.addItem).disposed(by: disposeBag) | |
scheduler.start() | |
print(result.events.debugDescription) | |
} | |
} | |
func inMemoryStack() -> NSManagedObjectContext { | |
let modelURL = Bundle.main.url(forResource: "CoreDataModel", withExtension: "momd")! | |
let managedObjectModel = NSManagedObjectModel(contentsOf: modelURL)! | |
let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel) | |
do { | |
try persistentStoreCoordinator.addPersistentStore(ofType: NSInMemoryStoreType, configurationName: nil, at: nil, options: nil) | |
} catch { | |
print("Adding in-memory persistent store failed") | |
} | |
let managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) | |
managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator | |
return managedObjectContext | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import XCTest | |
import CoreData | |
import RxCoreData | |
import RxSwift | |
@testable import CoreDataAppTarget | |
// General test for persisting objects. | |
class ViewModelTest: XCTestCase { | |
override func setUp() { | |
super.setUp() | |
} | |
override func tearDown() { | |
super.tearDown() | |
} | |
func testExample() { | |
let disposeBag = DisposeBag() | |
let moc = inMemoryStack() | |
let items = moc.rx.entities(Item.self, sortDescriptors: [NSSortDescriptor(key: "date", ascending: false)]).debug() | |
let item = Item(date: Date()) | |
do { try moc.rx.update(item) } catch { print(error) } | |
items.subscribe { (event) in | |
print("--- event: " + event.debugDescription) | |
}.disposed(by: disposeBag) | |
} | |
func inMemoryStack() -> NSManagedObjectContext { | |
let modelURL = Bundle.main.url(forResource: "CoreDataModel", withExtension: "momd")! | |
let managedObjectModel = NSManagedObjectModel(contentsOf: modelURL)! | |
let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel) | |
do { | |
try persistentStoreCoordinator.addPersistentStore(ofType: NSInMemoryStoreType, configurationName: nil, at: nil, options: nil) | |
} catch { | |
print("Adding in-memory persistent store failed") | |
} | |
let managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) | |
managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator | |
return managedObjectContext | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment