AngularFire 使用 RxJS Subject 测试对象是否存在

AngularFire testing for an object to exist using RxJS Subject

我正在尝试测试一个对象是否存在于我的 AngularFire table 中。我在 return 检测文件是否存在时遇到问题。

/**
 * Check if the Id exists in storage
 * @param Id string | number Key value to check
 * @returns Subject<boolean>
 */
public Exists(Id:string):Subject<boolean> {
    const Status$:Subject<boolean> = new Subject<boolean>();

    let RecordExists:boolean = false;
    this.AfDb_.object<T>(`_Testing_/${Id}`).valueChanges()
        .subscribe( (OneRecord:T) => {
            if (OneRecord.Key_ !== undefined && OneRecord.Key_ !== null && OneRecord.Key_.length > 0) {
                RecordExists = true;
            }
        })
    ;
    Status$.next(RecordExists);
    return Status$;
}

这始终是 return未定义的。我的自动化测试也失败了。

it('should confirm a record exists in storage', fakeAsync( () => {
    let Exists:boolean;
    const Status$:Subject<boolean> = ServiceUnderTest.Exists('Good');    // This exists in Firebase
    Status$.subscribe( (Result:boolean) => {
        Exists = Result;
    });
    flushMicrotasks();
    Status$.unsubscribe();
    expect(Exists).toBeTrue();
}));

我可以在 Firebase 中访问 /Testing/Good,这是一个具有 Key_ 和 Name 结构的对象。

模块来自 package.json

"@angular/fire": "^5.4.2",
"firebase": "^7.9.3",

但是,如果我只是尝试 return 一个结果而不直接进入 AngularFire,这些测试会起作用。

public Exists(Id:string):BehaviorSubject<boolean> {
    const Status:BehaviorSubject<boolean | undefined> = new BehaviorSubject<boolean | undefined>(undefined);

    Status.next(true);
    return Status;
}

RecordExists 来自 .valueChanges() 时,您必须在主题上调用 next 例如:

    let RecordExists:boolean = false;
    this.AfDb_.object<T>(`_Testing_/${Id}`).valueChanges()
        .subscribe( (OneRecord:T) => {


            if (OneRecord.Key_ !== undefined && OneRecord.Key_ !== null && OneRecord.Key_.length > 0) {
                Status$.next(true);
            } else {
                 Status$.next(false);
           }
        })
    ;
    return Status$;

您的代码在测试和简单示例中的行为方式不同,因为两者都以同步方式调用此 .valueChanges(),因此 .next()subscribe 之后调用。在现实生活中 valueChanges 是异步的,所以 subscribenext.

之前被调用

====================已编辑=====================

要连接真实数据库,您必须将测试修改为异步(因为连接是异步的:

it('should confirm a record exists in storage',((done) => {
    Status$.subscribe( (Result:boolean) => {
      expect(Exists).toBeTrue();
      done()
    });
d}))