【问题标题】:How to test angular 5 component with rxjs 5 forkJoin如何使用 rxjs 5 forkJoin 测试 Angular 5 组件
【发布时间】:2018-04-24 19:40:52
【问题描述】:

我的应用程序中有一个 ResultsComponent,我在其中同时进行两个服务调用,通过使用 rxjs forkJoin 运算符加入两个 observable。我想模拟 rxjs 运算符的数据。我有很多时间谷歌并尝试了不同的方法,但没有找到方法。谁能帮帮我。

角度版本:5.2.9 rxjs 版本:5.5.7 角-cli:1.6.6

results.component.ts

中的 forkJoin 语句中出现此错误

TypeError:您在预期流的位置提供了“未定义”。您可以提供 Observable、Promise、Array 或 Iterable。

results.component.ts

@Component({
  selector: "app-results",
  templateUrl: "./results.component.html",
  styleUrls: ["./results.component.scss"]
})
export class ResultsComponent 
  implements OnInit, OnDestroy {
  searchForm: FormGroup;


  constructor(
    private rxnsSearchService: RxnsSearchService,
    private rxnsSearchHitCountService: RxnsSearchHitCountService,
    public store: Store<fromAppReducer.AppState>,
    private route: ActivatedRoute,
    public formBuilder: FormBuilder,
    public router: Router
  ) {

  }

  ngOnInit() {

    this.route.queryParams.subscribe(params => {
      this.searchForm = this.formBuilder.group({
        searchInput: new FormControl(params.q, Validators.required),
        searchType: new FormControl(params.searchType),
        searchBy: new FormControl(params.searchBy)
      });
      this.store.dispatch(new AppActions.ChemQueryString(params.q));
      const rxnsObservable: Observable<Array<any>> = this.rxnsSearchService.getReactions(params, 0);
      const headCountObservable: Observable<number> = this.rxnsSearchHitCountService.getHitCount(params);
      forkJoin([rxnsObservable, headCountObservable]).subscribe(results => {
        this.reactions = results["0"];
        this.total = results["1"];
      }, (error) => {
        console.log(error);
      });
    });
    this.store.select("rxnState").subscribe(data => {
      console.log(data);
      this.searchString = data.slice(-1)[0].searchString;
    });
  }
  ngOnDestroy() {}
}

results.component.spec.ts

const dummydata = [
  {
    ruid: "02b01f46288b4f71950d03856bc8f173",
    rxnString: "Cl.NCCC1(C(F)(F)F)CC1.NCC1=CC=CC(NC"
  },
  {
    ruid: "02b01f46288b4f71950d03856bc8f173",
    rxnString: "Cl.NCCC1(C(F)(F)F)CC1.NCC1=CC=CC(NC"
  }
];
const dummyParams = {q: "[H]N(C(=O)C([H])([H])C)C1([H])CCCC22", searchType: "SUBSTRUCTURE", searchBy: "PRODUCT"};

class RouterStub {
  navigate(commands: any[], extras?: NavigationExtras) { }
}
class ActivatedRouteStub {
  private _testParams: {};
  private subject = new BehaviorSubject(this._testParams);
   queryParams = this.subject.asObservable();
  setQueryParams(params: Params) {
    this._testParams = params;
    this.subject.next(params);
  }
}

describe("ResultsComponent", () => {
  beforeEach(() => {
    activatedRoute = new ActivatedRouteStub();
  });
  let component: ResultsComponent;
  let injector;
  let store: Store<any>;
  let fixture: ComponentFixture<ResultsComponent>;
  let rxnsSearchService: RxnsSearchService;
  let rxnsSearchHitCountService: RxnsSearchHitCountService;
  let activatedRoute: ActivatedRouteStub;

  beforeEach(async(() => {

    TestBed.configureTestingModule({
      imports: [
        ResultsModule,
        NgxPaginationModule,
        HttpClientTestingModule,
        RouterTestingModule,
        StoreModule.forRoot(fromAppReducer.reducers)
      ],
      declarations: [ ],
      providers: [
          RxnsSearchService,
          RxnsSearchHitCountService,
        { provide: ActivatedRoute, useValue: activatedRoute },
        { provide: Router, useClass: RouterStub},
        FormBuilder
      ]
    }).compileComponents();
    injector = getTestBed();
    rxnsSearchService = injector.get(RxnsSearchService);
    rxnsSearchHitCountService = injector.get(RxnsSearchHitCountService);
    spyOn(rxnsSearchService, 'getReactions').and.returnValue(Observable.of(dummydata));
    spyOn(rxnsSearchHitCountService, 'getHitCount').and.returnValue(Observable.of(300));
    store = injector.get(Store);
  }));

  beforeEach(async(() => {
    activatedRoute.setQueryParams(dummyParams);
    fixture = TestBed.createComponent(ResultsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }));

  it("should create results component", () => {
    expect(component).toBeTruthy();
  });
});

【问题讨论】:

  • 看起来 rxnsObservableheadCountObservable 不是 Observable。
  • @martin 应用程序运行良好。
  • @martin 如果有更好的方法来模拟和编写测试用例也可以。我不想坚持我所写的。
  • 不要在组件中执行fork join。使用一个函数,然后你可以简单地测试它
  • 必须是 this.reactions = results[0]; this.total = 结果[1]; . NOT put " - 是一个数组-

标签: angular rxjs angular5 rxjs5


【解决方案1】:

我最近遇到了同样的问题,并通过将 forkjoin 拉出到它自己的方法中来解决它,然后创建一个间谍来返回我想要的值。

ngOnInit() {

  this.route.queryParams.subscribe(params => {
    this.searchForm = this.formBuilder.group({
      searchInput: new FormControl(params.q, Validators.required),
      searchType: new FormControl(params.searchType),
      searchBy: new FormControl(params.searchBy)
    });
    this.store.dispatch(new AppActions.ChemQueryString(params.q));
    const rxnsObservable: Observable<Array<any>> = this.rxnsSearchService.getReactions(params, 0);
    const headCountObservable: Observable<number> = this.rxnsSearchHitCountService.getHitCount(params);

    const data = this.getData(rxnsObservable, headCountObservable); 
    this.reactions = data["0"];
    this.total = data["1"];
  });
  this.store.select("rxnState").subscribe(data => {
    console.log(data);
    this.searchString = data.slice(-1)[0].searchString;
  });
}

getData(req1, req2) {
  forkJoin([req1, req2]).subscribe(results => {
    return results;
  }, (error) => {
    console.log(error);
  });
}

那么你的测试可以是这样的:

spyOn(component, 'getData').and.returnValue([foo, bar]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-02
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    相关资源
    最近更新 更多