Angular2和TestBed:如何模拟AngularFire2/observable数据服务?

Dan*_*son 5 unit-testing testbed firebase angularfire2 angular

我真的很难尝试了解TestBed的工作原理以及如何使用它来模拟数据检索(通过AngularFire2即observables)/推进离线单元测试.如果有人可以提供一个简单的例子来查看它让事情变得如此简单.

下面是StateService的(部分).然后我将此服务注入另一个组件并打印出graphModules名称,例如

图的modules.component.html

<div *ngFor="let module of s.graphModules$ | async"><div class="module-card">{{module.name}}</div></div>

图的modules.component.ts

constructor(public s: StateService){}

state.service.ts

@Injectable()
export class StateService {

 graphModules$: FirebaseListObservable<any>;
  private auth;

  constructor(public af: AngularFire) {
    af.auth.subscribe(
      latestAuth => {
        this.graphModules$ = af.database.list('/graphModules', {
          query: {
            orderByChild: 'archived',
            equalTo: false
          }
        });
      },
      errors => {
        this.auth = {uid: 'AUTH PROBLEMS'};
        throw 'Problems authenticating';
      }
    );
  }

  saveToDB(key: string, value: any) { 
     this.af.database.list('/graphModules').update(key, value);
     ...
  }
...
}
Run Code Online (Sandbox Code Playgroud)

我想要测试的是

1)给定"graphModules"的模拟/存根,将正确的.card模块数打印到DOM.

2)用s.saveToDB()更新其中一个模块后,在DOM中更新名称

另外,如果您对我的数据检索"架构"有其他意见,那么也是最受欢迎的:)

非常感谢!

编辑:

好的,我发现了如何修复1号.测试正确通过.问题2尚未得到解答.spec文件现在看起来像这样:

图的modules.component.spec.ts

class MockStateService {
  public graphModules$: Observable<GraphModule[]>;
  constructor () {
    this.graphModules$ = Observable.of<GraphModule[]>([
      {
        name: 'first',
        ...
      },
      {
        name: 'second',
        ...
      }
    ]);
  }
  updateGraphModule(key: string, value: any) {
    // Not sure what to put here in order to emit new value on graphModules$
  }
}



describe('ModulesComponent', () => {
  let fixture:  ComponentFixture<ModulesComponent>;
  beforeEach(() => {
    this.service = new MockStateService();
    TestBed.configureTestingModule({
      imports: [AppModule],
      providers: [{provide: StateService, useValue: this.service }]
    });
    fixture = TestBed.createComponent(ModulesComponent);
  });

  it('should print out two graphModules', async(() => {
    fixture.whenStable().then(() => {
      fixture.detectChanges();
      const test = fixture.nativeElement.querySelectorAll('.module-card');
      expect(fixture.nativeElement.querySelectorAll('.module-card').length).toBe(2);
    });
  }));


  it('should retrieve new data from observer and update DOM when the first graph-module has been given a new name', async(() => {
    fixture.whenStable().then(() => {
      fixture.detectChanges();
      this.service.updateGraphModule(0, {name: 'new name'});
      // What should I write here to test if the DOM is correctly updated?
    });
  }));
 }));
});
Run Code Online (Sandbox Code Playgroud)