Angular 如何将 Subject() 作为 Observable 进行测试
Angular how to test a Subject() as an Observable
我的问题是我不知道如何在订阅主题的组件上测试订阅,我的代码是这样的:
实用服务:
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 方法中订阅了那个 Subject,像这样:
this.utilService.getClearFlag().subscribe((value) => {
this.clearFlag = value;
});
这个主题的值由另外两个组件给出,如下所示:
this.utilService.setClearFlag(false);
我需要测试代码的订阅片段,但我不确定如何,我已经尝试了 Whosebug 上的每一个解决方案,但我不断收到此错误:
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();
})
);
我把注释掉的代码留在那儿,这样你就可以看到我试过的解决方案。
试试这个:
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();
其他的我觉得还不错。
我的问题是我不知道如何在订阅主题的组件上测试订阅,我的代码是这样的:
实用服务:
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 方法中订阅了那个 Subject,像这样:
this.utilService.getClearFlag().subscribe((value) => {
this.clearFlag = value;
});
这个主题的值由另外两个组件给出,如下所示:
this.utilService.setClearFlag(false);
我需要测试代码的订阅片段,但我不确定如何,我已经尝试了 Whosebug 上的每一个解决方案,但我不断收到此错误:
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();
})
);
我把注释掉的代码留在那儿,这样你就可以看到我试过的解决方案。
试试这个:
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();
其他的我觉得还不错。