如果对象是从全局后台QOS队列中保存的,则在测试期间无法获得Realm对象结果

时间:2018-07-04 12:22:29

标签: swift realm

我们在尝试测试处理Realm对象的特定方法时遇到问题。

这是测试方法

func testMarkPhotoAsViewedMethodNonExistingIdentityPhotosContainer() {

    let photoId = "id1"

    let albumMembershipData = AlbumMembershipData(unsafeResultMap: albumMembershipsFixture.first!)
    let rlmContainer = ViewedAlbumMembershipPhotosContainer()
    rlmContainer.albumMembershipId = albumMembershipData.membershipDetails().id

    let realm = try! Realm(configuration: realmConfig)

    try! realm.write {
        realm.add(rlmContainer)
    }

    try! service.markPhotoAsViewed(viewedPhotosContainer: rlmContainer,
                                   selectedIdentitiesIdentityIds: ["identity1", "identity2"],
                                   photo: ExtendedPhotoDetails(id: photoId),
                                   photoSetType: .matches)

    waitUntil(timeout: 10) { done in

        var identityContainer1: ViewedIdentityPhotosContainer? = nil
        var identityContainer2: ViewedIdentityPhotosContainer? = nil

        while(true) {

            identityContainer1 = self.service.getViewedPhotos(forIdentityId: "identity1")
            identityContainer2 = self.service.getViewedPhotos(forIdentityId: "identity2")

            if identityContainer1 != nil && identityContainer2 != nil {
                break
            }

        }

        expect(identityContainer1?.contains(photo: ExtendedPhotoDetails(id: photoId))) == true
        expect(identityContainer2?.contains(photo: ExtendedPhotoDetails(id: photoId))) == true

        done()

    }

}

这是正在测试的方法:

public func markPhotoAsViewed(viewedPhotosContainer: ViewedAlbumMembershipPhotosContainer,
                              selectedIdentitiesIdentityIds: [String]?,
                              photo: ExtendedPhotoDetails,
                              photoSetType: AlbumPhotoSet) throws
{

    log.verbose("⚙️ Marking photo \(photo.id) as viewed in photoset: \(photoSetType)")

    let realm = try! Realm(configuration: configuration)
    let threadSafeContainer = viewedPhotosContainer.toThreadConfinedObject(inRealm: realm) ?? viewedPhotosContainer

    do {

        try realm.write {
           threadSafeContainer.addViewedPhoto(withPhotoId: photo.id, forPhotoSetType: photoSetType)
        }

    } catch {
        log.error("❌ Error marking photo as viewed: \(error.localizedDescription)")
    }

    // If this a matched photo in the album, we need to mark any potential photos
    // in the appropriate identity viewed photos container
    guard let identityIds = selectedIdentitiesIdentityIds, photoSetType == .matches else { return }

    let queue = isRunningUnitTests() ? DispatchQueue.main : DispatchQueue.global(qos: .background)

    queue.async {

        let realm = try! Realm(configuration: self.configuration)

        for id in identityIds {

            var identityContainer: ViewedIdentityPhotosContainer? = nil

            if let container = realm.object(ofType: ViewedIdentityPhotosContainer.self, forPrimaryKey: id) {

                log.verbose("ℹ️ Container for identity id \(id ) already exists, adding photo entry...")
                identityContainer = container

            } else {

                log.verbose("ℹ️ Container for identity id \(id ) doesn't exist. Creating a new one...")
                identityContainer = ViewedIdentityPhotosContainer()
                identityContainer?.identityId = id

            }

            do {

                try realm.write {

                    if !(identityContainer?.photoIds.contains(photo.id) ?? true) {
                        identityContainer?.photoIds.append(photo.id)
                    }

                    realm.add(identityContainer!, update: true)

                }

            } catch {
                log.verbose("❌ Error appending photo \(photo.id) to identity container: \(id)")
            }

        }

    }

}

这是获取Realm结果的便捷方法:

 public func getViewedPhotos(forIdentityId identityId: String) -> ViewedIdentityPhotosContainer? {

    let realm = try! Realm(configuration: configuration)
    let predicate = NSPredicate(format: "identityId = %@", identityId)

    return realm.objects(ViewedIdentityPhotosContainer.self).filter(predicate).first

}

看来,如果我们在运行测试时未在markPhotoAsViewed方法中使用主队列,那么testMarkPhotoAsViewedMethodNonExistingIdentityPhotosContainer将永远无法获取identityContainer1identityContainer2

我怀疑这与Nimble实施其waitUntil方法的方式有关,但是我很想就纯粹出于教育目的为什么要这样做有一个明确的答案。

编辑:这是setUp()上的领域配置: realmConfig = Realm.Configuration.init(inMemoryIdentifier: self.name, deleteRealmIfMigrationNeeded: true)

0 个答案:

没有答案