【问题标题】:Angular how to test a Subject() as an ObservableAngular 如何将 Subject() 测试为 Observable
【发布时间】:2021-10-12 16:54:06
【问题描述】:

我的问题是我不知道如何在订阅主题的组件上测试订阅,我的代码是这样的:

实用服务:

private clearFlag = new Subject<boolean>();
public readonly message$ = this.clearFlag.asObservable();

getClearFlag(): Observable<boolean> {
  return this.message$;
}

setClearFlag(clear: boolean) {
  this.clearFlag.next(clear);
}

在组件中,我在 ngOnInit 方法中订阅了该主题,如下所示:

this.utilService.getClearFlag().subscribe((value) => {
      this.clearFlag = value;
    });

这个主题的价值由另外两个组件给出,如下所示:

this.utilService.setClearFlag(false);

我需要测试代码的订阅片段,但我不确定如何,我已经尝试了 StackOverflow 上的每一个解决方案,但我不断收到此错误:

Failed: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'subscribe')

规格文件:

describe('ContactsPageComponent', () => {
  let component: ContactsPageComponent;
  let fixture: ComponentFixture<ContactsPageComponent>;
  let utilServiceSpy: jasmine.SpyObj<UtilService>;
  let contactsHttpSpy: jasmine.SpyObj<ContactsHttpService>;
  let contactServiceSpy: jasmine.SpyObj<ContactService>;
  let qrSpy: jasmine.SpyObj<QrService>;
  let storeService: StorageService;
  // const clearFlag = new Subject<false>();


  beforeEach(
    waitForAsync(() => {
      utilServiceSpy = jasmine.createSpyObj('UtilService', [
        'getLoadingModal',
        'transactionStatus',
        'transactionStatusDescription',
        // 'getClearFlag',
        'setClearFlag',
      ]);

      ...

      TestBed.configureTestingModule({
        declarations: [ContactsPageComponent],
        imports: [
          IonicModule,
          CommonModule,
          HttpClientTestingModule,
          YpHeaderModule,
          RouterTestingModule,
          BrowserAnimationsModule,
          LottieModule,
        ],
        providers: [
          ...

          // { provide: UtilService, useValue: utilServiceSpy, clearFlag },

          { provide: UtilService, useValue: utilServiceSpy },

          ...

        ],
      }).compileComponents();


      fixture = TestBed.createComponent(ContactsPageComponent);
      component = fixture.componentInstance;
      component.clearFlag = false;

      fixture.detectChanges();

      const utilService = TestBed.inject(UtilService);

      // spyOn(utilService,'setClearFlag').and.returnValue();
      // spyOn(utilService,'setClearFlag').and.callFake(() => false);


      utilServiceSpy.setClearFlag(false);
      const spy = spyOn(utilService.message$, 'subscribe').and.callThrough();


      // const spy = jasmine.createSpyObj(UtilService, ['getClearFlag']);
      // utilServiceSpy.message$.subscribe(v => {
      //   expect(v).toBeDefined();
      // });
      // utilService.message$.subscribe(v => {
      //   expect(v).toBeDefined();
      // });

      component.ngOnInit();
      expect(component.clearFlag).toBeDefined();
      expect(spy).toHaveBeenCalled();
    })
  );

我把注释掉的代码留在了那里,这样你就可以看到我尝试过的解决方案。

【问题讨论】:

    标签: angular unit-testing jasmine karma-jasmine


    【解决方案1】:

    试试这个:

    import { of } from 'rxjs';
    ....
    waitForAsync(() => {
          utilServiceSpy = jasmine.createSpyObj('UtilService', [
            'getLoadingModal',
            'transactionStatus',
            'transactionStatusDescription',
            // uncomment getClearFlag
            'getClearFlag',
            'setClearFlag',
          ]);
        
         ....
         fixture = TestBed.createComponent(ContactsPageComponent);
         component = fixture.componentInstance;
         component.clearFlag = false;
         // return whatever you would like here
         utilServiceSpy.getClearFlag.and.returnValue(of(true));
         // the first fixture.detectChanges will run ngOnInit
         fixture.detectChanges();
         expect(component.clearFlag).toBeTrue();
    

    我觉得其余的都不错。

    【讨论】:

    • 是的!成功了,非常感谢。
    猜你喜欢
    • 2018-01-24
    • 2018-03-04
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-22
    相关资源
    最近更新 更多