首页 > 解决方案 > 在 .pipe angular 8 jasmine 内部测试可观察到

问题描述

我在我的组件中订阅了主题,triggerRuleExecutionService该主题正在next()从另一个组件中发出。

在管道内部,我switchMap必须调用 http 服务才能从数据库中获取数据

 this.ruleExecutionService = this.editCheckSVC.triggerRuleExecutionService.pipe(
      switchMap(res => {
        return this.editCheckSVC.executeRules(res);
      })
    ).subscribe(res => {
      console.log(res);
    });

上面的代码在里面ngOnInit

以下是我测试上述功能的规范。

    const ruleExecutionSubject = new Subject();

    class EditChkManagementServiceStub {
      triggerRuleExecutionService = ruleExecutionSubject.asObservable();
      executeRules() {
        return of([])
      }
   }



describe('EditcheckManagmentComponent', () => {
      let component: EditcheckManagmentComponent;
      let fixture: ComponentFixture<EditcheckManagmentComponent>;
      let debugElement: DebugElement;
      beforeEach(async(() => {
        TestBed.configureTestingModule({
          declarations: [EditcheckManagmentComponent],
          schemas: [NO_ERRORS_SCHEMA],
          providers: [{ provide: EditCheckManagementService, useClass: EditChkManagementServiceStub }, HttpService],
          imports: [HttpClientModule]
        })
          .compileComponents();
      }));

      beforeEach(() => {

        fixture = TestBed.createComponent(EditcheckManagmentComponent);
        component = fixture.componentInstance;
        debugElement = fixture.debugElement;
        fixture.detectChanges();
      });


    it('should call rule execution API', () => {
        ruleExecutionSubject.next({
          formName: '',
          schedule: '',
          subSchedule: '',
          version: '',
          fiscalYear: '2018',
          accountingPeriod: '6'
        });

        fixture.detectChanges();
        fixture.whenStable().then(() => {
          const executionServiceInstance: EditCheckManagementService = TestBed.get(EditCheckManagementService);
          spyOn(executionServiceInstance, 'executeRules').and.callThrough();
          component.ngOnInit()
          expect(executionServiceInstance.executeRules).toHaveBeenCalled();
        });

      });
    });

测试用例失败并显示消息Expected spy executeRules to have been called.

我在这里做错了什么?

标签: angulartypescriptjasminekarma-runner

解决方案


describe('EditcheckManagmentComponent', () => {
      let component: EditcheckManagmentComponent;
      let fixture: ComponentFixture<EditcheckManagmentComponent>;
      let debugElement: DebugElement;
      let mockEditChkManagementService: any;
      beforeEach(async(() => {
        mockEditChkManagementService = jasmine.createSpyObj('editCheckSVC', ['executeRules']);
        // can maybe create a variable BehaviorSubject so you can call next on it and send new values.
        mockEditChkManagemenetService.triggerRuleExecutionService = new BehaviorSubject({
         formName: '',
         schedule: '',
         subSchedule: '',
         version: '',
         fiscalYear: '2018',
         accountingPeriod: '6'
        });
        TestBed.configureTestingModule({
          declarations: [EditcheckManagmentComponent],
          schemas: [NO_ERRORS_SCHEMA],
          providers: [{ provide: EditCheckManagementService, useValue: mockEditChkManagemenetService}],
          imports: [HttpClientTestingModule] // bring in the testing HTTP, not actual implementation
        })
          .compileComponents();
      }));

      beforeEach(() => {

        fixture = TestBed.createComponent(EditcheckManagmentComponent);
        component = fixture.componentInstance;
        debugElement = fixture.debugElement;
        // make mockEditChkManagementService return an empty array
        mockEditChkManagementService.executeRules.and.returnValue(of([])); 
        // this first fixture.detectChanges() will call ngOnInit, no need to do it manually
        fixture.detectChanges();
      });


    it('should call rule execution API', () => {
       expect(mockEditChkManagementService.executeRules).toHaveBeenCalledWith({
         formName: '',
         schedule: '',
         subSchedule: '',
         version: '',
         fiscalYear: '2018',
         accountingPeriod: '6'
        });
      });
    });

试试看。要进行更多测试并进行简单设置,可能会很困难。您将不得不利用更多describe的 s、beforeEach等。

至于你有什么,我不确定有什么问题。


推荐阅读