2016-08-15 4 views
2

내 영속성 레이어에 realm-cocoa을 사용하고 있습니다.신속하게 realm-cocoa를 모의하는 방법

class RealmMetaData : AbstractMetaData { 
    var realm: RealmInterface 
    var isFirstLaunch: Bool = false 
    init(realm: RealmInterface = try! Realm()) { 
     self.realm = realm 
     let results = realm.objects(MyClass.self) 
     self.isFirstLaunch = (results.count == 0) 
     if (self.isFirstLaunch) { 
      realm.write { 
       realm.add(MyClass()) 
      } 
     } 
    } 
    // some code 
} 


protocol RealmInterface { 
    // using a protocol based approach of mocking 
    func objects<T: Object>(type: T.Type) -> Results<T> 
    func write(@noescape block: (() throws -> Void)) throws 
    func add(object: Object) 
} 

extension Realm: RealmInterface { 
    func add(object: Object) { self.add(object, update: false) } 
    // there is a method for Realm with signature: add(object:Object, update:Bool = false) 
    // but swift extension dose not permit default function parameter, hence the wrapping 
} 

realm 그런 다음 내 테스트 코드에서, 나는 RealmInterface의 조롱 버전을 쓸 수 및 Constructor Injection를 사용하여 RealmMetaData 인스턴스에 주입의 클래스 중 하나가 따라한다.

조롱 된 RealmInterface을 구현할 때 objects 함수를 모의 해 빈 목록을 반환하는 것은 매우 어려운 것으로 나타났습니다. 함수 시그니처 Results<T>의 반환 형식은 Realm Framework에서 제공하는 형식이므로 사용할 수있는 빈 생성자가 없습니다. 여기에 내가 붙어있는 곳이있다.

Result<T>final 키워드를 사용하는 클래스이므로 빈 컬렉션을 가져 오는 데 개인적인 방법으로 사용하기 위해 하위 클래스로 만들 수 없습니다.

미리 감사드립니다.

+0

마음에 오는 첫 번째 제안은 테스트 클래스 내의 메모리 렐름을 유지하고 관리하여이 모든 메소드를 메모리에 전달하는 것입니다. – Dmitry

+0

@ 드미트리 그래, 그 덕분에, 고마워. 이 의견을 답으로 써 주시면 받아 들일 수 있습니까? –

답변

1

의견에서 제안한 것처럼 내부 클래스 인 메모리를 테스트 클래스 내에서 사용하고 Result<T>을 반환하는 모든 메서드를 전달할 수 있습니다.

0

결국 결과 대신 자체 프로토콜을 반환합니다. 따라서 AnyRealmCollection<T>으로이 프로토콜을 구현하고 [T]으로 다른 프로토콜을 구현하므로 인 메모리 영역 객체가없는 테스트에서 쉽게 조롱합니다.

+0

이 방법을 이해했지만이 방법으로 테스트하기 쉽도록 코드를 변경하는 것은 좋지 않습니다. –

+0

@KevinR 무엇 때문에? – ReDetection

+0

두 개의 센트가 있지만 코드를 변경하면 코드가 복잡해지고 실수가 발생할 수 있습니다. 또한 테스트 중에 구현을 변경하면 실제로 프로덕션 코드에 사용 된 표현이 다른 결과를 초래할 수있는 경우 코드가 잘 작동한다고 생각할 수 있습니다. –

관련 문제